diff --git a/.github/workflows/configs/database.php b/.github/workflows/configs/database.php index 8e0bafa3a0..56a2868092 100644 --- a/.github/workflows/configs/database.php +++ b/.github/workflows/configs/database.php @@ -5,9 +5,10 @@ class DATABASE_CONFIG private $identities = [ 'mysql' => [ 'datasource' => 'Database/Mysql', - 'host' => '127.0.0.1', + 'host' => 'mysql', 'login' => 'root', - 'password' => 'root' + 'password' => 'root', + 'flags' => [PDO::ATTR_STRINGIFY_FETCHES => true], ], 'sqlite' => [ 'datasource' => 'Database/Sqlite', diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ba04115e8c..f6281e31f0 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -15,11 +15,15 @@ jobs: linux-tests: runs-on: ubuntu-latest + container: + image: ${{ matrix.container }} + strategy: fail-fast: false matrix: - php-version: - - '8.0' + container: + - 'beinbm/cake:php80' + - 'beinbm/cake:php82' db-type: - mysql - sqlite @@ -30,13 +34,7 @@ jobs: env: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: cakephp_test - ports: - - 3306:3306 options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 - redis: - image: redis - ports: - - 6379:6379 memcached: image: memcached ports: @@ -49,47 +47,43 @@ jobs: - name: Checkout uses: actions/checkout@v3 - - name: Install PHP with extensions - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-version }} - extensions: apcu, memcache, memcached, redis, mcrypt, pdo_mysql, pdo_sqlite - ini-values: | - assert.exception=1, - zend.assertions=1, - error_reporting=-1, - log_errors_max_len=0, - display_errors=On, - apc.enable_cli=1 - tools: composer - - - name: locale-gen - run: | - sudo locale-gen de_DE; - sudo locale-gen es_ES; +# - name: Install PHP with extensions +# uses: shivammathur/setup-php@v2 +# with: +# php-version: ${{ matrix.php-version }} +# extensions: apcu, memcache, memcached, mcrypt, pdo_mysql, pdo_sqlite +# ini-values: | +# assert.exception=1, +# zend.assertions=1, +# error_reporting=-1, +# log_errors_max_len=0, +# display_errors=On, +# apc.enable_cli=1 +# tools: composer + +# - name: locale-gen +# run: | +# sudo locale-gen de_DE; +# sudo locale-gen es_ES; - name: Create Another Databases for MySQL if: matrix.db-type == 'mysql' run: | - env MYSQL_PWD=root mysql -h 127.0.0.1 -u root -e 'CREATE DATABASE cakephp_test2;'; - env MYSQL_PWD=root mysql -h 127.0.0.1 -u root -e 'CREATE DATABASE cakephp_test3;'; + env MYSQL_PWD=root mysql -h mysql -u root -e 'CREATE DATABASE cakephp_test2;'; + env MYSQL_PWD=root mysql -h mysql -u root -e 'CREATE DATABASE cakephp_test3;'; - name: Make temporary directories writable run: chmod -R 777 ./app/tmp - - name: Composer get cache directory - id: composer-cache - run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - - name: Cache Composer + id: composer-cache uses: actions/cache@v3 with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-php${{ matrix.php-version }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: | - ${{ runner.os }}-php${{ matrix.php-version }}-composer- + path: ./vendor + key: ${{ matrix.container }}-composer-${{ hashFiles('**/composer.json') }} - name: Install Composer Packages + if: steps.composer-cache.outputs.cache-hit != 'true' run: composer install --no-ansi --no-interaction --no-progress - name: Copy database.php diff --git a/.gitignore b/.gitignore index 258a8fedbf..1bf3bffc34 100644 --- a/.gitignore +++ b/.gitignore @@ -29,5 +29,4 @@ Icon? ehthumbs.db Thumbs.db -composer.lock .phpunit.result.cache diff --git a/app/Config/Schema/db_acl.php b/app/Config/Schema/db_acl.php deleted file mode 100644 index 7dfc7f7ef8..0000000000 --- a/app/Config/Schema/db_acl.php +++ /dev/null @@ -1,101 +0,0 @@ - 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), - 'idx_acos_lft_rght' => array('column' => array('lft', 'rght'), 'unique' => 0), - 'idx_acos_alias' => array('column' => 'alias', 'unique' => 0) - ) - ); - -/** - * ARO - Access Request Object - Something that wants something - */ - 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), - 'idx_aros_lft_rght' => array('column' => array('lft', 'rght'), 'unique' => 0), - 'idx_aros_alias' => array('column' => 'alias', 'unique' => 0) - ) - ); - -/** - * Used by the Cake::Model:Permission class. - * Checks if the given $aro has access to action $action in $aco. - */ - 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), - 'idx_aco_id' => array('column' => 'aco_id', 'unique' => 0) - ) - ); - -} diff --git a/app/Config/Schema/db_acl.sql b/app/Config/Schema/db_acl.sql deleted file mode 100644 index e0a0e02fb1..0000000000 --- a/app/Config/Schema/db_acl.sql +++ /dev/null @@ -1,52 +0,0 @@ -# $Id$ -# -# Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) -# -# Licensed under The MIT License -# For full copyright and license information, please see the LICENSE.txt -# Redistributions of files must retain the above copyright notice. -# MIT License (https://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) -); - -/* this indexes will improve acl performance */ -CREATE INDEX idx_acos_lft_rght ON `acos` (`lft`, `rght`); - -CREATE INDEX idx_acos_alias ON `acos` (`alias`); - -CREATE INDEX idx_aros_lft_rght ON `aros` (`lft`, `rght`); - -CREATE INDEX idx_aros_alias ON `aros` (`alias`); - -CREATE INDEX idx_aco_id ON `aros_acos` (`aco_id`); diff --git a/app/Config/acl.ini.php b/app/Config/acl.ini.php deleted file mode 100644 index 5c890f50af..0000000000 --- a/app/Config/acl.ini.php +++ /dev/null @@ -1,65 +0,0 @@ -; -;/** -; * ACL Configuration -; * -; * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) -; * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) -; * -; * Licensed under The MIT License -; * Redistributions of files must retain the above copyright notice. -; * -; * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) -; * @link https://cakephp.org CakePHP(tm) Project -; * @package app.Config -; * @since CakePHP(tm) v 0.10.0.1076 -; * @license https://opensource.org/licenses/mit-license.php MIT License -; */ - -; acl.ini.php - CakePHP 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 diff --git a/app/Config/acl.php b/app/Config/acl.php deleted file mode 100644 index cddb9f47e5..0000000000 --- a/app/Config/acl.php +++ /dev/null @@ -1,145 +0,0 @@ -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, and Role/accountant. 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/app/Config/bootstrap.php b/app/Config/bootstrap.php index f4876d125c..b8c9716403 100644 --- a/app/Config/bootstrap.php +++ b/app/Config/bootstrap.php @@ -37,7 +37,6 @@ * '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/'), diff --git a/app/Config/core.php b/app/Config/core.php index 15e38bc031..be7d6aa2eb 100644 --- a/app/Config/core.php +++ b/app/Config/core.php @@ -267,13 +267,6 @@ */ //Configure::write('Asset.filter.js', 'custom_javascript_output_filter.php'); -/** - * The class name 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. diff --git a/composer.json b/composer.json index 57508a7492..fc58084cb4 100644 --- a/composer.json +++ b/composer.json @@ -20,11 +20,17 @@ "ext-mcrypt": "You need to install ext-openssl or ext-mcrypt to use AES-256 encryption" }, "require-dev": { - "phpunit/phpunit": "^9.5", - "rector/rector": "^0.15" + "phpunit/phpunit": "^9", + "rector/rector": "*" }, "config": { "vendor-dir": "vendor/", - "process-timeout": 0 + "process-timeout": 0, + "platform": { + "php": "8.0.30" + } + }, + "autoload": { + "exclude-from-classmap": [" /lib/Cake/Console/Templates/skel/", "/app/", "/lib/Cake/Test/test_app"] } } diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000000..adc5639d1a --- /dev/null +++ b/composer.lock @@ -0,0 +1,2052 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "bbb7b40c70eca965bf0839e824dc7254", + "packages": [ + { + "name": "phpseclib/mcrypt_compat", + "version": "1.0.15", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/mcrypt_compat.git", + "reference": "077eccc6970b723c00a30d95c70d67f892df0de7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/mcrypt_compat/zipball/077eccc6970b723c00a30d95c70d67f892df0de7", + "reference": "077eccc6970b723c00a30d95c70d67f892df0de7", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpseclib/phpseclib": ">=2.0.36 <3.0.0" + }, + "provide": { + "ext-mcrypt": "5.6.40" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35|^5.7|^6.0|^9.4" + }, + "suggest": { + "ext-openssl": "Will enable faster cryptographic operations" + }, + "type": "library", + "autoload": { + "files": [ + "lib/mcrypt.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "homepage": "http://phpseclib.sourceforge.net" + } + ], + "description": "PHP 7.1 polyfill for the mcrypt extension from PHP <= 7.0", + "keywords": [ + "cryptograpy", + "encryption", + "mcrypt" + ], + "support": { + "email": "terrafrost@php.net", + "issues": "https://github.com/phpseclib/mcrypt_compat/issues", + "source": "https://github.com/phpseclib/mcrypt_compat" + }, + "funding": [ + { + "url": "https://www.patreon.com/phpseclib", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpseclib/mcrypt_compat", + "type": "tidelift" + } + ], + "time": "2022-12-18T12:17:52+00:00" + }, + { + "name": "phpseclib/phpseclib", + "version": "2.0.44", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "149f608243f8133c61926aae26ce67d2b22b37e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/149f608243f8133c61926aae26ce67d2b22b37e5", + "reference": "149f608243f8133c61926aae26ce67d2b22b37e5", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phing/phing": "~2.7", + "phpunit/phpunit": "^4.8.35|^5.7|^6.0|^9.4", + "squizlabs/php_codesniffer": "~2.0" + }, + "suggest": { + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations.", + "ext-xml": "Install the XML extension to load XML formatted public keys." + }, + "type": "library", + "autoload": { + "files": [ + "phpseclib/bootstrap.php" + ], + "psr-4": { + "phpseclib\\": "phpseclib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com", + "role": "Developer" + } + ], + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "homepage": "http://phpseclib.sourceforge.net", + "keywords": [ + "BigInteger", + "aes", + "asn.1", + "asn1", + "blowfish", + "crypto", + "cryptography", + "encryption", + "rsa", + "security", + "sftp", + "signature", + "signing", + "ssh", + "twofish", + "x.509", + "x509" + ], + "support": { + "issues": "https://github.com/phpseclib/phpseclib/issues", + "source": "https://github.com/phpseclib/phpseclib/tree/2.0.44" + }, + "funding": [ + { + "url": "https://github.com/terrafrost", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpseclib", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", + "type": "tidelift" + } + ], + "time": "2023-06-13T08:41:47+00:00" + } + ], + "packages-dev": [ + { + "name": "doctrine/instantiator", + "version": "1.5.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b", + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9 || ^11", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^0.16 || ^1", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-phpunit": "^1", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.30 || ^5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "https://ocramius.github.io/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.5.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2022-12-30T00:15:36+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.11.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2023-03-08T13:26:56+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.16.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "19526a33fb561ef417e822e85f08a00db4059c17" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/19526a33fb561ef417e822e85f08a00db4059c17", + "reference": "19526a33fb561ef417e822e85f08a00db4059c17", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.16.0" + }, + "time": "2023-06-25T14:52:30+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.3" + }, + "time": "2021-07-20T11:28:43+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "1.10.28", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "e4545b55904ebef470423d3ddddb74fa7325497a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e4545b55904ebef470423d3ddddb74fa7325497a", + "reference": "e4545b55904ebef470423d3ddddb74fa7325497a", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", + "type": "tidelift" + } + ], + "time": "2023-08-08T12:33:42+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "9.2.27", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "b0a88255cb70d52653d80c890bd7f38740ea50d1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/b0a88255cb70d52653d80c890bd7f38740ea50d1", + "reference": "b0a88255cb70d52653d80c890bd7f38740ea50d1", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.15", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0.3", + "phpunit/php-text-template": "^2.0.2", + "sebastian/code-unit-reverse-lookup": "^2.0.2", + "sebastian/complexity": "^2.0", + "sebastian/environment": "^5.1.2", + "sebastian/lines-of-code": "^1.0.3", + "sebastian/version": "^3.0.1", + "theseer/tokenizer": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.27" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-07-26T13:44:30+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "3.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-12-02T12:48:52+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:58:55+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T05:33:50+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:16:10+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "9.6.10", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "a6d351645c3fe5a30f5e86be6577d946af65a328" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a6d351645c3fe5a30f5e86be6577d946af65a328", + "reference": "a6d351645c3fe5a30f5e86be6577d946af65a328", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.3.1 || ^2", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=7.3", + "phpunit/php-code-coverage": "^9.2.13", + "phpunit/php-file-iterator": "^3.0.5", + "phpunit/php-invoker": "^3.1.1", + "phpunit/php-text-template": "^2.0.3", + "phpunit/php-timer": "^5.0.2", + "sebastian/cli-parser": "^1.0.1", + "sebastian/code-unit": "^1.0.6", + "sebastian/comparator": "^4.0.8", + "sebastian/diff": "^4.0.3", + "sebastian/environment": "^5.1.3", + "sebastian/exporter": "^4.0.5", + "sebastian/global-state": "^5.0.1", + "sebastian/object-enumerator": "^4.0.3", + "sebastian/resource-operations": "^3.0.3", + "sebastian/type": "^3.2", + "sebastian/version": "^3.0.2" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.6-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.10" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2023-07-10T04:04:23+00:00" + }, + { + "name": "rector/rector", + "version": "0.17.12", + "source": { + "type": "git", + "url": "https://github.com/rectorphp/rector.git", + "reference": "af3a14a8a9fffa3100b730571c356f6c658d5e09" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/af3a14a8a9fffa3100b730571c356f6c658d5e09", + "reference": "af3a14a8a9fffa3100b730571c356f6c658d5e09", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "phpstan/phpstan": "^1.10.26" + }, + "conflict": { + "rector/rector-doctrine": "*", + "rector/rector-downgrade-php": "*", + "rector/rector-phpunit": "*", + "rector/rector-symfony": "*" + }, + "bin": [ + "bin/rector" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Instant Upgrade and Automated Refactoring of any PHP code", + "keywords": [ + "automation", + "dev", + "migration", + "refactoring" + ], + "support": { + "issues": "https://github.com/rectorphp/rector/issues", + "source": "https://github.com/rectorphp/rector/tree/0.17.12" + }, + "funding": [ + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2023-08-10T15:22:02+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:08:49+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:08:54+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:30:19+00:00" + }, + { + "name": "sebastian/comparator", + "version": "4.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-14T12:41:17+00:00" + }, + { + "name": "sebastian/complexity", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.7", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T15:52:27+00:00" + }, + { + "name": "sebastian/diff", + "version": "4.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/74be17022044ebaaecfdf0c5cd504fc9cd5a7131", + "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-05-07T05:35:17+00:00" + }, + { + "name": "sebastian/environment", + "version": "5.1.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:03:51+00:00" + }, + { + "name": "sebastian/exporter", + "version": "4.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-14T06:03:37+00:00" + }, + { + "name": "sebastian/global-state", + "version": "5.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "bde739e7565280bda77be70044ac1047bc007e34" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bde739e7565280bda77be70044ac1047bc007e34", + "reference": "bde739e7565280bda77be70044ac1047bc007e34", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-02T09:26:13+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.6", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-28T06:42:11+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:12:34+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:14:26+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "4.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:07:39+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:45:17+00:00" + }, + { + "name": "sebastian/type", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:13:03+00:00" + }, + { + "name": "sebastian/version", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c6c1022351a901512170118436c764e473f6de8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", + "reference": "c6c1022351a901512170118436c764e473f6de8c", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:39:44+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2021-07-28T10:34:58+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": "^8.0" + }, + "platform-dev": [], + "platform-overrides": { + "php": "8.0.30" + }, + "plugin-api-version": "2.3.0" +} diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 975b985340..039ff3eca4 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -1,10 +1,11 @@ services: web: # image: beinbm/cake:php74 # enable for php7.4+xdebug - image: beinbm/cake:php80 # enable for php8.0+xdebug - # build: # enable for own builds - # context: ./docker/web - # dockerfile: PHP74.Dockerfile +# image: beinbm/cake:php80 # enable for php8.0+xdebug + image: beinbm/cake:php82 # enable for php8.0+xdebug +# build: # enable for own builds +# context: ./docker/web +# dockerfile: PHP82.Dockerfile # platform: "linux/amd64" environment: #XDEBUG_SESSION: "core" diff --git a/docker-compose.yml b/docker-compose.yml index d7ec37c992..ad487d4e54 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,27 +1,26 @@ services: web: - image: beinbm/cake:php80 # override in override file + image: beinbm/cake:php82 # override in override file environment: PHP_IDE_CONFIG: "serverName=localhost" volumes: - ./:/var/www/html:cached working_dir: /var/www/html ports: - - "8000:80" + - "8080:80" depends_on: - mysql - memcached - - redis mysql: image: mysql:5.7 platform: linux/amd64 - command: mysqld --character-set-server=utf8 --collation-server=utf8_general_ci +# command: mysqld --character-set-server=utf8 --collation-server=utf8_general_ci environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: cakephp_test volumes: - ./docker/mysql:/docker-entrypoint-initdb.d:cached - - dev-db-data:/var/lib/mysql + - dev-db-data2:/var/lib/mysql # ports: # - "3306:3306" memcached: @@ -29,10 +28,5 @@ services: hostname: memcached # ports: # - "11211:11211" - redis: - image: "redis:latest" - hostname: redis -# ports: -# - "6379:6379" volumes: - dev-db-data: + dev-db-data2: diff --git a/docker/web/PHP74.Dockerfile b/docker/web/PHP74.Dockerfile index c28bd0c1de..c68ed4a907 100644 --- a/docker/web/PHP74.Dockerfile +++ b/docker/web/PHP74.Dockerfile @@ -1,12 +1,12 @@ -FROM php:7.4-apache +FROM php:7.4-apache-bullseye RUN apt-get update && apt-get install -y --no-install-recommends \ && apt-get install -y libzip-dev unzip openssl libmcrypt-dev libmemcached-dev locales \ && rm -rf /var/lib/apt/lists/* RUN docker-php-ext-install pdo_mysql zip \ - && pecl install apcu redis memcached mcrypt \ - && docker-php-ext-enable redis memcached mcrypt \ + && pecl install apcu memcached mcrypt xdebug-3.1.6 pcov \ + && docker-php-ext-enable memcached mcrypt xdebug \ && echo "extension=apcu.so" >> /usr/local/etc/php/php.ini \ && echo "apc.enable_cli = 1" >> /usr/local/etc/php/php.ini @@ -22,6 +22,3 @@ RUN a2enmod rewrite RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf - -RUN pecl install xdebug-3.1.6 && pecl install pcov -RUN docker-php-ext-enable xdebug diff --git a/docker/web/PHP80.Dockerfile b/docker/web/PHP80.Dockerfile index af07d75fe2..1643f25d69 100644 --- a/docker/web/PHP80.Dockerfile +++ b/docker/web/PHP80.Dockerfile @@ -1,12 +1,12 @@ -FROM php:8.0-apache +FROM php:8.0-apache-bullseye RUN apt-get update && apt-get install -y --no-install-recommends \ && apt-get install -y libzip-dev unzip openssl libmcrypt-dev libmemcached-dev locales \ && rm -rf /var/lib/apt/lists/* RUN docker-php-ext-install pdo_mysql zip \ - && pecl install apcu redis memcached mcrypt \ - && docker-php-ext-enable redis memcached mcrypt \ + && pecl install apcu memcached mcrypt xdebug pcov \ + && docker-php-ext-enable memcached mcrypt xdebug \ && echo "extension=apcu.so" >> /usr/local/etc/php/php.ini \ && echo "apc.enable_cli = 1" >> /usr/local/etc/php/php.ini @@ -23,5 +23,4 @@ RUN a2enmod rewrite RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf -RUN pecl install xdebug && pecl install pcov -RUN docker-php-ext-enable xdebug +RUN apt-get update && apt-get install -y default-mysql-client nodejs zstd diff --git a/docker/web/PHP82.Dockerfile b/docker/web/PHP82.Dockerfile new file mode 100644 index 0000000000..ad3695a22c --- /dev/null +++ b/docker/web/PHP82.Dockerfile @@ -0,0 +1,28 @@ +FROM php:8.2-apache-bullseye + +RUN apt-get update && apt-get install -y --no-install-recommends \ + && apt-get install -y libzip-dev unzip openssl libmcrypt-dev libmemcached-dev locales vim \ + && rm -rf /var/lib/apt/lists/* + +RUN docker-php-ext-install pdo_mysql zip \ + && pecl install apcu memcached mcrypt \ + && docker-php-ext-enable memcached mcrypt \ + && echo "extension=apcu.so" >> /usr/local/etc/php/php.ini \ + && echo "apc.enable_cli = 1" >> /usr/local/etc/php/php.ini + +COPY --from=composer /usr/bin/composer /usr/local/bin/composer + +RUN sed -i '/de_DE /s/^# //g' /etc/locale.gen \ + && sed -i '/es_ES /s/^# //g' /etc/locale.gen \ + && locale-gen + +ENV APACHE_DOCUMENT_ROOT /var/www/html/app/webroot + +RUN a2enmod rewrite + +RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf +RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf + +RUN pecl install xdebug && docker-php-ext-enable xdebug + +RUN apt-get update && apt-get install -y default-mysql-client nodejs zstd diff --git a/lib/Cake/Cache/Engine/MemcacheEngine.php b/lib/Cake/Cache/Engine/MemcacheEngine.php deleted file mode 100644 index d70c1c56df..0000000000 --- a/lib/Cake/Cache/Engine/MemcacheEngine.php +++ /dev/null @@ -1,312 +0,0 @@ - 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 bool 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 (strpos($server, 'unix://') === 0) { - 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 int $duration How long to cache the data, in seconds - * @return bool 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 int $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 %s not implemented for compressed cache in %s', 'increment()', __CLASS__) - ); - } - return $this->_Memcache->increment($key, $offset); - } - -/** - * Decrements the value of an integer cached key - * - * @param string $key Identifier for the data - * @param int $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 %s not implemented for compressed cache in %s', 'decrement()', __CLASS__) - ); - } - return $this->_Memcache->decrement($key, $offset); - } - -/** - * Delete a key from the cache - * - * @param string $key Identifier for the data - * @return bool 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 bool $check If true no deletes will occur and instead CakePHP will rely - * on key TTL values. - * @return bool True if the cache was successfully cleared, false otherwise - */ - public function clear($check) { - if ($check) { - return true; - } - foreach ($this->_Memcache->getExtendedStats('slabs', 0) as $slabs) { - foreach (array_keys($slabs) as $slabId) { - if (!is_numeric($slabId)) { - continue; - } - - foreach ($this->_Memcache->getExtendedStats('cachedump', $slabId, 0) 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 int $port Server port - * @return bool 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. - * - * @param string $group The group to clear. - * @return bool success - */ - public function clearGroup($group) { - return (bool)$this->_Memcache->increment($this->settings['prefix'] . $group); - } - -/** - * Write data for key into cache if it doesn't exist already. When using memcached as your cache engine - * remember that the Memcached 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. - * If it already exists, it fails and returns false. - * - * @param string $key Identifier for the data. - * @param mixed $value Data to be cached. - * @param int $duration How long to cache the data, in seconds. - * @return bool True if the data was successfully cached, false on failure. - * @link http://php.net/manual/en/memcache.add.php - */ - public function add($key, $value, $duration) { - if ($duration > 30 * DAY) { - $duration = 0; - } - - return $this->_Memcache->add($key, $value, $this->settings['compress'], $duration); - } -} diff --git a/lib/Cake/Cache/Engine/RedisEngine.php b/lib/Cake/Cache/Engine/RedisEngine.php deleted file mode 100644 index 6dd6599442..0000000000 --- a/lib/Cake/Cache/Engine/RedisEngine.php +++ /dev/null @@ -1,258 +0,0 @@ - 'Redis', - 'prefix' => Inflector::slug(APP_DIR) . '_', - 'server' => '127.0.0.1', - 'database' => 0, - 'port' => 6379, - 'password' => false, - 'timeout' => 0, - 'persistent' => true, - 'unix_socket' => false - ), $settings) - ); - - return $this->_connect(); - } - -/** - * Connects to a Redis server - * - * @return bool True if Redis server was connected - */ - protected function _connect() { - try { - $this->_Redis = new Redis(); - if (!empty($this->settings['unix_socket'])) { - $return = $this->_Redis->connect($this->settings['unix_socket']); - } elseif (empty($this->settings['persistent'])) { - $return = $this->_Redis->connect($this->settings['server'], $this->settings['port'], $this->settings['timeout']); - } else { - $persistentId = $this->settings['port'] . $this->settings['timeout'] . $this->settings['database']; - $return = $this->_Redis->pconnect($this->settings['server'], $this->settings['port'], $this->settings['timeout'], $persistentId); - } - } catch (RedisException $e) { - $return = false; - } - if (!$return) { - return false; - } - if ($this->settings['password'] && !$this->_Redis->auth($this->settings['password'])) { - return false; - } - return $this->_Redis->select($this->settings['database']); - } - -/** - * Write data for key into cache. - * - * @param string $key Identifier for the data - * @param mixed $value Data to be cached - * @param int $duration How long to cache the data, in seconds - * @return bool True if the data was successfully cached, false on failure - */ - public function write($key, $value, $duration) { - if (!is_int($value)) { - $value = serialize($value); - } - - if (!$this->_Redis->isConnected()) { - $this->_connect(); - } - - 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 (preg_match('/^[-]?\d+$/', $value)) { - return (int)$value; - } - if ($value !== false && is_string($value)) { - return unserialize($value); - } - return $value; - } - -/** - * Increments the value of an integer cached key - * - * @param string $key Identifier for the data - * @param int $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 int $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 bool 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 bool $check Whether or not expiration keys should be checked. If - * true, no keys will be removed as cache will rely on redis TTL's. - * @return bool 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. - * - * @param string $group The group name to clear. - * @return bool success - */ - public function clearGroup($group) { - return (bool)$this->_Redis->incr($this->settings['prefix'] . $group); - } - -/** - * Disconnects from the redis server - */ - public function __destruct() { - if (empty($this->settings['persistent']) && $this->_Redis !== null) { - $this->_Redis->close(); - } - } - -/** - * Write data for key into cache if it doesn't exist already. - * If it already exists, it fails and returns false. - * - * @param string $key Identifier for the data. - * @param mixed $value Data to be cached. - * @param int $duration How long to cache the data, in seconds. - * @return bool True if the data was successfully cached, false on failure. - * @link https://github.com/phpredis/phpredis#setnx - */ - public function add($key, $value, $duration) { - if (!is_int($value)) { - $value = serialize($value); - } - - $result = $this->_Redis->setnx($key, $value); - // setnx() doesn't have an expiry option, so overwrite the key with one - if ($result) { - return $this->_Redis->setex($key, $duration, $value); - } - return false; - } -} diff --git a/lib/Cake/Cache/Engine/WincacheEngine.php b/lib/Cake/Cache/Engine/WincacheEngine.php deleted file mode 100644 index dc83481715..0000000000 --- a/lib/Cake/Cache/Engine/WincacheEngine.php +++ /dev/null @@ -1,207 +0,0 @@ - '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 int $duration How long to cache the data, in seconds - * @return bool 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 = (int)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 int $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 int $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 bool 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 bool $check If true, nothing will be cleared, as entries will - * naturally expire in wincache.. - * @return bool 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. - * - * @param string $group The group to clear. - * @return bool success - */ - public function clearGroup($group) { - $success = null; - wincache_ucache_inc($this->settings['prefix'] . $group, 1, $success); - return $success; - } - -/** - * Write data for key into cache if it doesn't exist already. - * If it already exists, it fails and returns false. - * - * @param string $key Identifier for the data. - * @param mixed $value Data to be cached. - * @param int $duration How long to cache the data, in seconds. - * @return bool True if the data was successfully cached, false on failure. - */ - public function add($key, $value, $duration) { - $cachedValue = $this->read($key); - if ($cachedValue === false) { - return $this->write($key, $value, $duration); - } - return false; - } -} diff --git a/lib/Cake/Configure/IniReader.php b/lib/Cake/Configure/IniReader.php index 2c7bc76337..5b4b30c0ab 100644 --- a/lib/Cake/Configure/IniReader.php +++ b/lib/Cake/Configure/IniReader.php @@ -88,7 +88,7 @@ public function __construct($path = null, $section = null) { /** * Read an ini file and return the results as an array. * - * For backwards compatibility, acl.ini.php will be treated specially until 3.0. + * For backwards compatibility * * @param string $key The identifier to read from. If the key has a . it will be treated * as a plugin prefix. The chosen file must be on the reader's path. diff --git a/lib/Cake/Console/Command/AclShell.php b/lib/Cake/Console/Command/AclShell.php deleted file mode 100644 index 10db318eb2..0000000000 --- a/lib/Cake/Console/Command/AclShell.php +++ /dev/null @@ -1,619 +0,0 @@ -params['connection'])) { - $this->connection = $this->params['connection']; - } - - $class = Configure::read('Acl.classname'); - list($plugin, $class) = pluginSplit($class, true); - App::uses($class, $plugin . 'Controller/Component/Acl'); - if (!in_array($class, array('DbAcl', 'DB_ACL')) && !is_subclass_of($class, 'DbAcl')) { - $out = "--------------------------------------------------\n"; - $out .= __d('cake_console', 'Error: Your current CakePHP 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', $class) . "\n"; - $out .= "--------------------------------------------------\n"; - $this->err($out); - return $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.')); - $this->args = null; - return $this->DbConfig->execute(); - } - require_once CONFIG . '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', "New %s '%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. Note there may be (as a result of poor configuration) - * multiple records with the same logical identifier. All are deleted. - * - * @return void - */ - public function delete() { - extract($this->_dataVars()); - - $identifier = $this->parseIdentifier($this->args[1]); - if (is_string($identifier)) { - $identifier = array('alias' => $identifier); - } - - if ($this->Acl->{$class}->find('all', array('conditions' => $identifier))) { - if (!$this->Acl->{$class}->deleteAll($identifier)) { - $this->error(__d('cake_console', 'Node Not Deleted. ') . __d('cake_console', 'There was an error deleting the %s.', $class) . "\n"); - } - $this->out(__d('cake_console', '%s deleted.', $class), 2); - } else { - $this->error(__d('cake_console', 'Node Not Deleted. ') . __d('cake_console', 'There was an error deleting the %s. Node does not exist.', $class) . "\n"); - } - } - -/** - * 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.')); - } else { - $this->out(__d('cake_console', 'Node parent set to %s', $this->args[2]) . "\n"); - } - } - -/** - * 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 int $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 allowed.', $aroName)); - } else { - $this->out(__d('cake_console', '%s is not allowed.', $aroName)); - } - } - -/** - * 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 granted.')); - } else { - $this->out(__d('cake_console', 'Permission was not granted.')); - } - } - -/** - * 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.')); - } else { - $this->out(__d('cake_console', 'Permission was not denied.')); - } - } - -/** - * 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.')); - } else { - $this->out(__d('cake_console', 'Permission was not inherited.')); - } - } - -/** - * 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'); - } - -/** - * Gets the option parser instance and configures it. - * - * @return ConsoleOptionParser - */ - 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 under the parent'), - 'epilog' => __d('cake_console', 'You can use `root` as the parent when creating nodes to create top level nodes.'), - '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 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 beneath '), - '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 .'), - '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 ."), - __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:', - '', - ' - . - The node will be bound to a specific record of the given model.', - '', - ' - - The node will be given a string alias (or path, in the case of )', - " i.e. 'John'. When used with , this takes the form of an alias path,", - " i.e. //.", - '', - "To add a node at the root level, enter 'root' or '/' as the parameter." - )); - - return $parser; - } - -/** - * Checks that given node exists - * - * @return bool 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|null $identifier A mixed identifier for finding the node, otherwise null. - * @return int 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 null; - } - 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]) ? (int)$this->args[0] : $this->args[0]; - $aco = is_numeric($this->args[1]) ? (int)$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) { - $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/lib/Cake/Console/Command/BakeShell.php b/lib/Cake/Console/Command/BakeShell.php deleted file mode 100644 index e0db7bc0c2..0000000000 --- a/lib/Cake/Console/Command/BakeShell.php +++ /dev/null @@ -1,255 +0,0 @@ -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']; - } - } - if (isset($this->params['connection'])) { - $this->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': - return $this->_stop(); - 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', 'Bake All complete'), 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(); - } - -/** - * Gets the option parser instance and configures it. - * - * @return ConsoleOptionParser - */ - public function getOptionParser() { - $parser = parent::getOptionParser(); - - $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 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' - ))->addOption('theme', array( - 'short' => 't', - 'help' => __d('cake_console', 'Theme to use when baking code.') - )); - - return $parser; - } - -} diff --git a/lib/Cake/Console/Command/SchemaShell.php b/lib/Cake/Console/Command/SchemaShell.php deleted file mode 100644 index 6a704bda81..0000000000 --- a/lib/Cake/Console/Command/SchemaShell.php +++ /dev/null @@ -1,573 +0,0 @@ -_welcome(); - $this->out('Cake Schema Shell'); - $this->hr(); - - Configure::write('Cache.disable', true); - - $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 && empty($this->params['file'])) { - $this->params['file'] = Inflector::underscore($name); - } elseif (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; - } - } - $name = Inflector::camelize($name); - $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()); - return $this->_stop(); - } - $file = $this->Schema->path . DS . $this->params['file']; - $this->err(__d('cake_console', 'Schema file (%s) could not be found.', $file)); - return $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['models'] = false; - } elseif (!empty($this->params['models'])) { - $options['models'] = CakeText::tokenize($this->params['models']); - } - - $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 (!empty($this->params['exclude']) && !empty($content)) { - $excluded = CakeText::tokenize($this->params['exclude']); - foreach ($excluded as $table) { - unset($content['tables'][$table]); - } - } - - if ($snapshot === true) { - $fileName = basename($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'])); - return $this->_stop(); - } - $this->err(__d('cake_console', 'Schema file: %s generated')); - return $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')); - return $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())); - return $this->_stop(); - } - $this->err(__d('cake_console', 'SQL dump could not be created')); - return $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, - 'connection' => $this->params['connection'], - ); - if (!empty($this->params['snapshot'])) { - $fileName = basename($this->Schema->file, '.php'); - $options['file'] = $fileName . '_' . $this->params['snapshot'] . '.php'; - } - - $Schema = $this->Schema->load($options); - - if (!$Schema) { - $this->err(__d('cake_console', 'Error: The chosen schema could not be loaded. Attempted to load:')); - $this->err(__d('cake_console', '- file: %s', $this->Schema->path . DS . $this->Schema->file)); - $this->err(__d('cake_console', '- name: %s', $this->Schema->name)); - return $this->_stop(2); - } - $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 The schema instance to create. - * @param string $table The table name. - * @return void - */ - protected function _create(CakeSchema $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.')); - return $this->_stop(); - } - - $this->out("\n" . __d('cake_console', 'The following table(s) will be dropped.')); - $this->out(array_keys($drop)); - - if (!empty($this->params['yes']) || - $this->in(__d('cake_console', 'Are you sure you want to drop the table(s)?'), array('y', 'n'), 'n') === 'y' - ) { - $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 (!empty($this->params['yes']) || - $this->in(__d('cake_console', 'Are you sure you want to create the table(s)?'), array('y', 'n'), 'y') === '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 The schema instance - * @param string $table The table name. - * @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) { - if (isset($compare[$table]['create'])) { - $contents[$table] = $db->createSchema($Schema, $table); - } else { - $contents[$table] = $db->alterSchema(array($table => $compare[$table]), $table); - } - } - } elseif (isset($compare[$table])) { - if (isset($compare[$table]['create'])) { - $contents[$table] = $db->createSchema($Schema, $table); - } else { - $contents[$table] = $db->alterSchema(array($table => $compare[$table]), $table); - } - } - - if (empty($contents)) { - $this->out(__d('cake_console', 'Schema is up to date.')); - return $this->_stop(); - } - - $this->out("\n" . __d('cake_console', 'The following statements will run.')); - $this->out(array_map('trim', $contents)); - if (!empty($this->params['yes']) || - $this->in(__d('cake_console', 'Are you sure you want to alter the tables?'), array('y', 'n'), 'n') === 'y' - ) { - $this->out(); - $this->out(__d('cake_console', 'Updating Database...')); - $this->_run($contents, 'update', $Schema); - - Configure::write('Cache.disable', false); - Cache::clear(false, '_cake_model_'); - } - - $this->out(__d('cake_console', 'End update.')); - } - -/** - * Runs sql from _create() or _update() - * - * @param array $contents The contents to execute. - * @param string $event The event to fire - * @param CakeSchema $Schema The schema instance. - * @return void - */ - protected function _run($contents, $event, CakeSchema $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)); - } - } - } - } - } - -/** - * Gets the option parser instance and configures it. - * - * @return ConsoleOptionParser - */ - public function getOptionParser() { - $parser = parent::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' => CONFIG . 'Schema' - ); - $file = array( - 'help' => __d('cake_console', 'File name to read and write.'), - ); - $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.') - ); - $models = array( - 'short' => 'm', - 'help' => __d('cake_console', 'Specify models as comma separated list.'), - ); - $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.') - ); - $exclude = array( - 'help' => __d('cake_console', 'Tables to exclude as comma separated list.') - ); - $yes = array( - 'short' => 'y', - 'help' => __d('cake_console', 'Do not prompt for confirmation. Be careful!'), - 'boolean' => true - ); - - $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', 'models', 'exclude'), - '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', 'yes'), - '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', 'yes'), - '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/lib/Cake/Console/Command/ServerShell.php b/lib/Cake/Console/Command/ServerShell.php deleted file mode 100644 index 014d3978a7..0000000000 --- a/lib/Cake/Console/Command/ServerShell.php +++ /dev/null @@ -1,167 +0,0 @@ -_host = static::DEFAULT_HOST; - $this->_port = static::DEFAULT_PORT; - $this->_documentRoot = WWW_ROOT; - } - -/** - * 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 https://book.cakephp.org/2.0/en/console-and-shells.html#Shell::startup - */ - public function startup() { - if (!empty($this->params['host'])) { - $this->_host = $this->params['host']; - } - if (!empty($this->params['port'])) { - $this->_port = $this->params['port']; - } - if (!empty($this->params['document_root'])) { - $this->_documentRoot = $this->params['document_root']; - } - - // for Windows - if (substr($this->_documentRoot, -1, 1) === DIRECTORY_SEPARATOR) { - $this->_documentRoot = substr($this->_documentRoot, 0, strlen($this->_documentRoot) - 1); - } - if (preg_match("/^([a-z]:)[\\\]+(.+)$/i", $this->_documentRoot, $m)) { - $this->_documentRoot = $m[1] . '\\' . $m[2]; - } - - parent::startup(); - } - -/** - * Displays a header for the shell - * - * @return void - */ - protected function _welcome() { - $this->out(); - $this->out(__d('cake_console', 'Welcome to CakePHP %s Console', 'v' . Configure::version())); - $this->hr(); - $this->out(__d('cake_console', 'App : %s', APP_DIR)); - $this->out(__d('cake_console', 'Path: %s', APP)); - $this->out(__d('cake_console', 'DocumentRoot: %s', $this->_documentRoot)); - $this->hr(); - } - -/** - * Override main() to handle action - * - * @return void - */ - public function main() { - if (version_compare(PHP_VERSION, '5.4.0') < 0) { - $this->out(__d('cake_console', 'This command is available on %s or above', 'PHP5.4')); - return; - } - - $command = sprintf("php -S %s:%d -t %s %s", - $this->_host, - $this->_port, - escapeshellarg($this->_documentRoot), - escapeshellarg($this->_documentRoot . '/index.php') - ); - - $port = ($this->_port == static::DEFAULT_PORT) ? '' : ':' . $this->_port; - $this->out(__d('cake_console', 'built-in server is running in http://%s%s/', $this->_host, $port)); - system($command); - } - -/** - * Gets the option parser instance and configures it. - * - * @return ConsoleOptionParser - */ - public function getOptionParser() { - $parser = parent::getOptionParser(); - - $parser->description(array( - __d('cake_console', 'PHP Built-in Server for CakePHP'), - __d('cake_console', '[WARN] Don\'t use this at the production environment') - ))->addOption('host', array( - 'short' => 'H', - 'help' => __d('cake_console', 'ServerHost') - ))->addOption('port', array( - 'short' => 'p', - 'help' => __d('cake_console', 'ListenPort') - ))->addOption('document_root', array( - 'short' => 'd', - 'help' => __d('cake_console', 'DocumentRoot') - )); - - return $parser; - } -} diff --git a/lib/Cake/Console/Command/Task/BakeTask.php b/lib/Cake/Console/Command/Task/BakeTask.php deleted file mode 100644 index c886c95e63..0000000000 --- a/lib/Cake/Console/Command/Task/BakeTask.php +++ /dev/null @@ -1,92 +0,0 @@ -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/lib/Cake/Console/Command/Task/CommandTask.php b/lib/Cake/Console/Command/Task/CommandTask.php index 99c888f8e8..92080ecd99 100644 --- a/lib/Cake/Console/Command/Task/CommandTask.php +++ b/lib/Cake/Console/Command/Task/CommandTask.php @@ -133,7 +133,7 @@ public function subCommands($commandName) { public function getShell($commandName) { list($pluginDot, $name) = pluginSplit($commandName, true); - if (in_array(strtolower($pluginDot), array('app.', 'core.'))) { + if (!empty($pluginDot) && in_array(strtolower($pluginDot), array('app.', 'core.'))) { $commandName = $name; $pluginDot = ''; } diff --git a/lib/Cake/Console/Command/Task/ControllerTask.php b/lib/Cake/Console/Command/Task/ControllerTask.php deleted file mode 100644 index 433329d6fa..0000000000 --- a/lib/Cake/Console/Command/Task/ControllerTask.php +++ /dev/null @@ -1,514 +0,0 @@ -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(); - - $admin = false; - if (!empty($this->params['admin'])) { - $admin = $this->Project->getPrefix(); - } - - $controllersCreated = 0; - 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 ($admin) { - $this->out(__d('cake_console', 'Adding %s methods', $admin)); - $actions .= "\n" . $this->bakeActions($controller, $admin); - } - if ($this->bake($controller, $actions) && $unitTestExists) { - $this->bakeTest($controller); - } - $controllersCreated++; - } - } - - if (!$controllersCreated) { - $this->out(__d('cake_console', 'No Controllers were baked, Models need to exist before Controllers can be baked.')); - } - } - -/** - * 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 the FlashComponent to display flash messages?"), array('y', 'n'), 'y' - ); - - if (strtolower($wannaUseSession) === 'y') { - array_push($components, 'Session', 'Flash'); - } - array_unique($components); - } - } 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 The name of the controller. - * @param string $useDynamicScaffold Whether or not to use dynamic scaffolds. - * @param array $helpers The list of helpers to include. - * @param array $components The list of components to include. - * @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 bool $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.')); - return $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); - - if ($helpers === null) { - $helpers = array(); - } - if ($components === null) { - $components = array(); - } - $isScaffold = ($actions === 'scaffold') ? true : false; - - $this->Template->set(array( - 'plugin' => $this->plugin, - 'pluginPath' => empty($this->plugin) ? '' : $this->plugin . '.' - )); - - if (!in_array('Paginator', (array)$components)) { - $components[] = 'Paginator'; - } - - $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: 'Text, Js, Time'") - ); - } - -/** - * Interact with the user and get a list of additional components - * - * @return array Components the user wants to use. - */ - public function doComponents() { - $components = array('Paginator'); - return array_merge($components, $this->_doPropertyChoices( - __d('cake_console', "Would you like this controller to use other components\nbesides PaginatorComponent?"), - __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 ($useDbConfig === null) { - $useDbConfig = $this->connection; - } - $this->__tables = $this->Model->getAllTables($useDbConfig); - - if ($this->interactive) { - $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 || (int)$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 ((int)$enteredController > 0 && (int)$enteredController <= count($controllers)) { - $controllerName = $controllers[(int)$enteredController - 1]; - } else { - $controllerName = Inflector::camelize($enteredController); - } - return $controllerName; - } - -/** - * Gets the option parser instance and configures it. - * - * @return ConsoleOptionParser - */ - public function getOptionParser() { - $parser = parent::getOptionParser(); - - $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.') - ))->addOption('theme', array( - 'short' => 't', - 'help' => __d('cake_console', 'Theme to use when baking code.') - ))->addOption('force', array( - 'short' => 'f', - 'help' => __d('cake_console', 'Force overwriting existing files without prompting.') - ))->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.') - ); - - return $parser; - } - -} diff --git a/lib/Cake/Console/Command/Task/DbConfigTask.php b/lib/Cake/Console/Command/Task/DbConfigTask.php deleted file mode 100644 index 8e23600877..0000000000 --- a/lib/Cake/Console/Command/Task/DbConfigTask.php +++ /dev/null @@ -1,377 +0,0 @@ - '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 = CONFIG; - } - -/** - * Execution method always used for tasks - * - * @return void - */ - public function execute() { - if (empty($this->args)) { - $this->_interactive(); - return $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) { - $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', 'Sqlite'), '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) { - $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 = ''; - - $config = compact('name', 'datasource', 'persistent', 'host', 'login', 'password', 'database', 'prefix', 'encoding', 'port', 'schema'); - - while (!$this->_verify($config)) { - $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 The config data. - * @return bool True if user says it looks good, false otherwise - */ - protected function _verify($config) { - $config += $this->_defaultConfig; - 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 bool 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 += $this->_defaultConfig; - - if (!isset($info['schema'])) { - $info['schema'] = null; - } - if (!isset($info['encoding'])) { - $info['encoding'] = null; - } - if (!isset($info['port'])) { - $info['port'] = null; - } - - $info['persistent'] = var_export((bool)$info['persistent'], true); - - $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 $config) { - if ($oldConfig['name'] === $config['name']) { - unset($oldConfigs[$key]); - } - } - } - - $configs = array_merge($oldConfigs, $configs); - $out = "_defaultConfig; - extract($config); - - if (strpos($datasource, 'Database/') === false) { - $datasource = "Database/{$datasource}"; - } - $out .= "\tpublic \${$name} = array(\n"; - $out .= "\t\t'datasource' => '{$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; - } - -/** - * Gets the option parser instance and configures it. - * - * @return ConsoleOptionParser - */ - public function getOptionParser() { - $parser = parent::getOptionParser(); - - $parser->description( - __d('cake_console', 'Bake new database configuration settings.') - ); - - return $parser; - } - -} diff --git a/lib/Cake/Console/Command/Task/FixtureTask.php b/lib/Cake/Console/Command/Task/FixtureTask.php deleted file mode 100644 index 7b2ee52e7d..0000000000 --- a/lib/Cake/Console/Command/Task/FixtureTask.php +++ /dev/null @@ -1,467 +0,0 @@ -path = APP . 'Test' . DS . 'Fixture' . DS; - } - -/** - * Gets the option parser instance and configures it. - * - * @return ConsoleOptionParser - */ - public function getOptionParser() { - $parser = parent::getOptionParser(); - - $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' => 1 - ))->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('schema', array( - 'help' => __d('cake_console', 'Importing schema for fixtures rather than hardcoding it.'), - 'short' => 's', - 'boolean' => true - ))->addOption('theme', array( - 'short' => 't', - 'help' => __d('cake_console', 'Theme to use when baking code.') - ))->addOption('force', array( - 'short' => 'f', - 'help' => __d('cake_console', 'Force overwriting existing files without prompting.') - ))->addOption('records', array( - 'help' => __d('cake_console', 'Used with --count and /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.') - ); - - return $parser; - } - -/** - * 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]); - $importOptions = $this->importOptions($model); - $this->bake($model, false, $importOptions); - } - } - -/** - * 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); - $importOptions = array(); - if (!empty($this->params['schema'])) { - $importOptions['schema'] = $model; - } - $this->bake($model, false, $importOptions); - } - } - -/** - * 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(); - $plugin = ''; - if (isset($this->params['plugin'])) { - $plugin = $this->params['plugin'] . '.'; - } - - if (!empty($this->params['schema'])) { - $options['schema'] = $plugin . $modelName; - } elseif ($this->interactive) { - $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; - } - } - - if (!empty($this->params['records'])) { - $options['fromTable'] = true; - } elseif ($this->interactive) { - $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 (!isset($options['records']) && $this->interactive) { - $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|null Baked fixture content, otherwise null. - */ - 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("Warning: Could not find the '${useTable}' table for ${model}."); - return null; - } - - $tableInfo = $data['tables'][$useTable]; - if ($modelImport === null) { - $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')); - 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 = trim($this->_Schema->generateTable('f', $tableInfo), "\n"); - return substr($schema, 13, -1); - } - -/** - * Generate String representation of Records - * - * @param array $tableInfo Table schema array - * @param int $recordCount The number of records to generate. - * @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; - } - $insert = ''; - switch ($fieldInfo['type']) { - case 'tinyinteger': - case 'smallinteger': - case 'biginteger': - 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 = CakeText::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 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) { - $modelObject = new Model(array('name' => $modelName, 'table' => $useTable, 'ds' => $this->connection)); - 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'); - } - - $recordsFound = $modelObject->find('count', array( - 'conditions' => $condition, - 'recursive' => -1, - )); - - $prompt = __d('cake_console', "How many records do you want to import?"); - $recordCount = $this->in($prompt, null, ($recordsFound < 10 ) ? $recordsFound : 10); - } else { - $condition = 'WHERE 1=1'; - $recordCount = (isset($this->params['count']) ? $this->params['count'] : 10); - } - - $records = $modelObject->find('all', array( - 'conditions' => $condition, - 'recursive' => -1, - 'limit' => $recordCount - )); - - $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/lib/Cake/Console/Command/Task/ModelTask.php b/lib/Cake/Console/Command/Task/ModelTask.php deleted file mode 100644 index f70cf656d5..0000000000 --- a/lib/Cake/Console/Command/Task/ModelTask.php +++ /dev/null @@ -1,1057 +0,0 @@ -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 int $default The default option for the given prompt. - * @return int 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 ((int)$choice > 0 && (int)$choice <= $max) { - $valid = true; - } - } - return $choice - 1; - } - -/** - * Handles interactive baking - * - * @return bool - */ - 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); - } - $displayField = null; - 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 (!$model instanceof Model) { - return false; - } - - $fields = $model->schema(); - if (empty($fields)) { - return false; - } - - $skipFields = false; - $validate = array(); - $this->initValidations(); - foreach ($fields as $fieldName => $field) { - $validation = $this->fieldValidation($fieldName, $field, $model->primaryKey); - if (isset($validation['_skipFields'])) { - unset($validation['_skipFields']); - $skipFields = true; - } - if (!empty($validation)) { - $validate[$fieldName] = $validation; - } - if ($skipFields) { - return $validate; - } - } - return $validate; - } - -/** - * Populate the _validations array - * - * @return void - */ - public function initValidations() { - $options = $choices = array(); - if (class_exists('Validation')) { - $options = get_class_methods('Validation'); - } - $deprecatedOptions = array('notEmpty', 'between', 'ssn'); - $options = array_diff($options, $deprecatedOptions); - sort($options); - $default = 1; - foreach ($options as $option) { - if ($option[0] !== '_') { - $choices[$default] = $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 The primary key field. - * @return array Array of validation for the field. - */ - public function fieldValidation($fieldName, $metaData, $primaryKey = 'id') { - $defaultChoice = count($this->_validations); - $validate = $alreadyChosen = array(); - - $prompt = __d('cake_console', - "or enter in a valid regex validation string.\nAlternatively [s] skip the rest of the fields.\n" - ); - $methods = array_flip($this->_validations); - - $anotherValidator = 'y'; - while ($anotherValidator === 'y') { - if ($this->interactive) { - $this->out(); - $this->out(__d('cake_console', 'Field: %s', $fieldName)); - $this->out(__d('cake_console', 'Type: %s', $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)); - if ($m + $i !== $defaultChoice) { - $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(); - } - - $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['notBlank']; - } elseif ($metaData['type'] === 'text') { - $guess = $methods['notBlank']; - } elseif ($metaData['type'] === 'integer') { - $guess = $methods['numeric']; - } elseif ($metaData['type'] === 'smallinteger') { - $guess = $methods['numeric']; - } elseif ($metaData['type'] === 'tinyinteger') { - $guess = $methods['numeric']; - } elseif ($metaData['type'] === 'float') { - $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']; - } elseif ($metaData['type'] === 'decimal') { - $guess = $methods['decimal']; - } - } - - if ($this->interactive === true) { - $choice = $this->in($prompt, null, $guess); - if ($choice === 's') { - $validate['_skipFields'] = true; - return $validate; - } - 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) { - $validate[$validatorName] = $choice; - if (is_numeric($choice) && isset($this->_validations[$choice])) { - $validate[$validatorName] = $this->_validations[$choice]; - } - } - $anotherValidator = 'n'; - if ($this->interactive && $choice != $defaultChoice) { - $anotherValidator = $this->in(__d('cake_console', "Would you like to add another validation rule\n" . - "or skip the rest of the fields?"), array('y', 'n', 's'), 'n'); - if ($anotherValidator === 's') { - $validate['_skipFields'] = true; - return $validate; - } - } - } - return $validate; - } - -/** - * Handles associations - * - * @param Model $model The model object - * @return array Associations - */ - public function doAssociations($model) { - if (!$model instanceof 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; - } - -/** - * Handles behaviors - * - * @param Model $model The model object. - * @return array Behaviors - */ - public function doActsAs($model) { - if (!$model instanceof Model) { - return false; - } - $behaviors = array(); - $fields = $model->schema(true); - if (empty($fields)) { - return array(); - } - - if (isset($fields['lft']) && $fields['lft']['type'] === 'integer' && - isset($fields['rght']) && $fields['rght']['type'] === 'integer' && - isset($fields['parent_id'])) { - $behaviors[] = 'Tree'; - } - return $behaviors; - } - -/** - * 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) { - $fieldNames = array_keys($model->schema(true)); - foreach ($fieldNames as $fieldName) { - $offset = substr($fieldName, -3) === '_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); - $tempFieldNames = array_keys($tempOtherModel->schema(true)); - - $pattern = '/_' . preg_quote($model->table, '/') . '|' . preg_quote($model->table, '/') . '_/'; - $possibleJoinTable = preg_match($pattern, $otherTable); - if ($possibleJoinTable) { - continue; - } - foreach ($tempFieldNames as $fieldName) { - $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) { - $tableName = null; - $offset = strpos($otherTable, $model->table . '_'); - $otherOffset = strpos($otherTable, '_' . $model->table); - - if ($offset !== false) { - $tableName = substr($otherTable, strlen($model->table . '_')); - } elseif ($otherOffset !== false) { - $tableName = substr($otherTable, 0, $otherOffset); - } - if ($tableName && in_array($tableName, $this->_tables)) { - $habtmName = $this->_modelName($tableName); - $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 (strtolower($response) === 'n') { - 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 = (int)$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[(int)$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|bool $data if array and $name is not an object assume bake data, otherwise boolean. - * @return string - */ - public function bake($name, $data = array()) { - if ($name instanceof Model) { - if (!$data) { - $data = array(); - $data['associations'] = $this->doAssociations($name); - $data['validate'] = $this->doValidation($name); - $data['actsAs'] = $this->doActsAs($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(), - 'actsAs' => 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 = $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 (without prefix)?')); - } - } - 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.')); - return $this->_stop(); - } - sort($tables); - 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')); - return $this->_stop(); - } - - if (!$enteredModel || (int)$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 ((int)$enteredModel > 0 && (int)$enteredModel <= count($this->_modelNames)) { - return $this->_modelNames[(int)$enteredModel - 1]; - } - - return $enteredModel; - } - -/** - * Gets the option parser instance and configures it. - * - * @return ConsoleOptionParser - */ - public function getOptionParser() { - $parser = parent::getOptionParser(); - - $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('theme', array( - 'short' => 't', - 'help' => __d('cake_console', 'Theme to use when baking code.') - ))->addOption('connection', array( - 'short' => 'c', - 'help' => __d('cake_console', 'The connection the model table is on.') - ))->addOption('force', array( - 'short' => 'f', - 'help' => __d('cake_console', 'Force overwriting existing files without prompting.') - ))->epilog( - __d('cake_console', 'Omitting all arguments and options will enter into an interactive mode.') - ); - - return $parser; - } - -/** - * 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/lib/Cake/Console/Command/Task/PluginTask.php b/lib/Cake/Console/Command/Task/PluginTask.php deleted file mode 100644 index 10a00864a4..0000000000 --- a/lib/Cake/Console/Command/Task/PluginTask.php +++ /dev/null @@ -1,236 +0,0 @@ -path = current(App::path('plugins')); - $this->bootstrap = CONFIG . '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; - } - $this->_interactive($plugin); - } else { - return $this->_interactive(); - } - } - -/** - * Interactive interface - * - * @param string $plugin The plugin name. - * @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 bool - */ - public function bake($plugin) { - $pathOptions = App::path('plugins'); - if (count($pathOptions) > 1) { - $this->findPath($pathOptions); - } - $this->hr(); - $this->out(__d('cake_console', "Plugin Name: %s", $plugin)); - $this->out(__d('cake_console', "Plugin Directory: %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', - 'Console' . DS . 'Command' . DS . 'Task', - 'Console' . DS . 'Templates', - 'Controller' . DS . 'Component', - 'Lib', - 'Locale' . DS . 'eng' . DS . 'LC_MESSAGES', - 'Model' . DS . 'Behavior', - 'Model' . DS . 'Datasource', - 'Test' . DS . 'Case' . DS . 'Controller' . DS . 'Component', - 'Test' . DS . 'Case' . DS . 'Lib', - 'Test' . DS . 'Case' . DS . 'Model' . DS . 'Behavior', - 'Test' . DS . 'Case' . DS . 'Model' . DS . 'Datasource', - 'Test' . DS . 'Case' . DS . 'View' . DS . 'Helper', - 'Test' . DS . 'Fixture', - 'View' . DS . 'Elements', - 'View' . DS . 'Helper', - 'View' . DS . 'Layouts', - 'webroot' . DS . 'css', - 'webroot' . DS . 'js', - 'webroot' . DS . 'img', - ); - - foreach ($directories as $directory) { - $dirPath = $this->path . $plugin . DS . $directory; - $Folder->create($dirPath); - 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 = "createFile($this->path . $plugin . DS . 'Controller' . DS . $controllerFileName, $out); - - $modelFileName = $plugin . 'AppModel.php'; - - $out = "createFile($this->path . $plugin . DS . 'Model' . DS . $modelFileName, $out); - - $this->_modifyBootstrap($plugin); - - $this->hr(); - $this->out(__d('cake_console', 'Created: %s in %s', $plugin, $this->path . $plugin), 2); - } - - return true; - } - -/** - * Update the app's bootstrap.php file. - * - * @param string $plugin Name of plugin - * @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 The list of paths to look in. - * @return void - */ - public function findPath($pathOptions) { - $valid = false; - foreach ($pathOptions as $i => $path) { - if (!is_dir($path)) { - unset($pathOptions[$i]); - } - } - $pathOptions = array_values($pathOptions); - - $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 ((int)$choice > 0 && (int)$choice <= $max) { - $valid = true; - } - } - $this->path = $pathOptions[$choice - 1]; - } - -/** - * Gets the option parser instance and configures it. - * - * @return ConsoleOptionParser - */ - public function getOptionParser() { - $parser = parent::getOptionParser(); - - $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.') - )); - - return $parser; - } - -} diff --git a/lib/Cake/Console/Command/Task/ProjectTask.php b/lib/Cake/Console/Command/Task/ProjectTask.php deleted file mode 100644 index ed38f6855b..0000000000 --- a/lib/Cake/Console/Command/Task/ProjectTask.php +++ /dev/null @@ -1,453 +0,0 @@ -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 && is_dir($project) === true && file_exists($project . 'Config' . 'core.php')) { - $prompt = __d('cake_console', 'A project already exists in this location: %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', CONFIG . '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', CONFIG . 'core.php')); - $success = false; - } - - if ($this->cachePrefix($path)) { - $this->out(__d('cake_console', ' * Cache prefix set')); - } else { - $this->err(__d('cake_console', 'The cache prefix was NOT set')); - $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', 'CakePHP is on your `include_path`. CAKE_CORE_INCLUDE_PATH will be set, but commented out.')); - } else { - $this->out(__d('cake_console', 'CakePHP is not on your `include_path`, CAKE_CORE_INCLUDE_PATH will be hard coded.')); - $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 %s', CAKE_CORE_INCLUDE_PATH, 'webroot/index.php')); - $this->out(__d('cake_console', ' * CAKE_CORE_INCLUDE_PATH set to %s in %s', CAKE_CORE_INCLUDE_PATH, 'webroot/test.php')); - } 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', ' * Remember to check these values after moving to production server')); - } - - $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('chmod -R 0777 ' . $path . DS . 'tmp'); - $success = false; - } - if ($success) { - $this->out(__d('cake_console', 'Project baked successfully!')); - } else { - $this->out(__d('cake_console', 'Project baked but with some issues..')); - } - return $path; - } - } - -/** - * Checks PHP's include_path for CakePHP. - * - * @return bool 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', 'Skel Directory: ') . $skel); - $this->out(__d('cake_console', 'Will be copied to: ') . $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', 'Created: %s in %s', $app, $path)); - $this->hr(); - } else { - $this->err(__d('cake_console', "Could not create '%s' properly.", $app)); - return false; - } - - foreach ($Folder->messages() as $message) { - $this->out(CakeText::wrap(' * ' . $message), 1, Shell::VERBOSE); - } - - return true; - case 'n': - unset($this->args[0]); - $this->execute(); - return false; - case 'q': - $this->out(__d('cake_console', 'Bake Aborted.')); - 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 bool 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 bool 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 bool 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; - } - -/** - * Writes cache prefix using app's name - * - * @param string $dir Path to project - * @return bool Success - */ - public function cachePrefix($dir) { - $app = basename($dir); - $File = new File($dir . 'Config' . DS . 'core.php'); - $contents = $File->read(); - if (preg_match('/(\$prefix = \'myapp_\';)/', $contents, $match)) { - $result = str_replace($match[0], '$prefix = \'' . $app . '_\';', $contents); - return $File->write($result); - } - return false; - } - -/** - * Generates and writes CAKE_CORE_INCLUDE_PATH - * - * @param string $path Project path - * @param bool $hardCode Whether or not define calls should be hardcoded. - * @return bool 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 bool $hardCode Whether or not the define should be uncommented. - * @return bool 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)) . "'"; - - $composer = ROOT . DS . APP_DIR . DS . 'Vendor' . DS . 'cakephp' . DS . 'cakephp' . DS . 'lib'; - if (file_exists($composer)) { - $corePath = " ROOT . DS . APP_DIR . DS . 'Vendor' . DS . 'cakephp' . DS . 'cakephp' . DS . 'lib'"; - } - - $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; - } - return (bool)$count; - } - -/** - * Enables Configure::read('Routing.prefixes') in /app/Config/core.php - * - * @param string $name Name to use as admin routing - * @return bool Success - */ - public function cakeAdmin($name) { - $path = (empty($this->configPath)) ? CONFIG : $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; - } - } - 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 %s in %s to use prefix routing.', - 'Configure::write(\'Routing.prefixes\', array(\'admin\'))', - '/app/Config/core.php')); - $this->out(__d('cake_console', 'What would you like the prefix route to be?')); - $this->out(__d('cake_console', 'Example: %s', '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', 'Unable to write to %s.', '/app/Config/core.php')); - $this->out(__d('cake_console', 'You need to enable %s in %s to use prefix routing.', - 'Configure::write(\'Routing.prefixes\', array(\'admin\'))', - '/app/Config/core.php')); - return $this->_stop(); - } - return $admin . '_'; - } - return ''; - } - -/** - * Gets the option parser instance and configures it. - * - * @return ConsoleOptionParser - */ - public function getOptionParser() { - $parser = parent::getOptionParser(); - - $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('theme', array( - 'short' => 't', - 'help' => __d('cake_console', 'Theme to use when baking code.') - ))->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.') - )); - - return $parser; - } - -} diff --git a/lib/Cake/Console/Command/Task/TemplateTask.php b/lib/Cake/Console/Command/Task/TemplateTask.php deleted file mode 100644 index 0691bf5c2a..0000000000 --- a/lib/Cake/Console/Command/Task/TemplateTask.php +++ /dev/null @@ -1,217 +0,0 @@ - $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; - - 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) { - 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/lib/Cake/Console/Command/Task/TestTask.php b/lib/Cake/Console/Command/Task/TestTask.php deleted file mode 100644 index 342494e577..0000000000 --- a/lib/Cake/Console/Command/Task/TestTask.php +++ /dev/null @@ -1,582 +0,0 @@ - 'Model', - 'Controller' => 'Controller', - 'Component' => 'Controller/Component', - 'Behavior' => 'Model/Behavior', - 'Helper' => 'View/Helper' - ); - -/** - * Mapping between packages, and their baseclass + package. - * This is used to generate App::uses() call to autoload base - * classes if a developer has forgotten to do so. - * - * @var array - */ - public $baseTypes = array( - 'Model' => array('Model', 'Model'), - 'Behavior' => array('ModelBehavior', 'Model'), - 'Controller' => array('Controller', 'Controller'), - 'Component' => array('Component', 'Controller'), - 'Helper' => array('Helper', 'View') - ); - -/** - * 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(); - $count = count($this->args); - if (!$count) { - $this->_interactive(); - } - - if ($count === 1) { - $this->_interactive($this->args[0]); - } - - if ($count > 1) { - $type = Inflector::classify($this->args[0]); - if ($this->bake($type, $this->args[1])) { - $this->out('Done'); - } - } - } - -/** - * Handles interactive baking - * - * @param string $type The type of object to bake a test for. - * @return string|bool - */ - 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|bool - */ - 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(); - } - list($baseClass, $baseType) = $this->getBaseType($type); - App::uses($baseClass, $baseType); - 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 bool - */ - 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 bool - */ - 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::uses($class, $type); - $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 class name - */ - 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 the base class and package name for a given type. - * - * @param string $type The type the class having a test - * generated for is in. - * @return array Array of (class, type) - * @throws CakeException on invalid types. - */ - public function getBaseType($type) { - if (empty($this->baseTypes[$type])) { - throw new CakeException(__d('cake_dev', 'Invalid type name')); - } - return $this->baseTypes[$type]; - } - -/** - * 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 CakeObject $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 ($subject instanceof Model) { - $this->_processModel($subject); - } elseif ($subject instanceof 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(, $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(, $model) = pluginSplit($model); - $this->_processModel($subject->{$model}); - } - } - -/** - * Add class name 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 bool - */ - public function hasMockClass($type) { - $type = strtolower($type); - return $type === 'controller'; - } - -/** - * Generate a constructor code snippet for the type and class name - * - * @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 & class name - * - * @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(); - $type = strtolower($type); - 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'; - } - -/** - * Gets the option parser instance and configures it. - * - * @return ConsoleOptionParser - */ - public function getOptionParser() { - $parser = parent::getOptionParser(); - - $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('theme', array( - 'short' => 't', - 'help' => __d('cake_console', 'Theme to use when baking code.') - ))->addOption('plugin', array( - 'short' => 'p', - 'help' => __d('cake_console', 'CamelCased name of the plugin to bake tests for.') - ))->addOption('force', array( - 'short' => 'f', - 'help' => __d('cake_console', 'Force overwriting existing files without prompting.') - ))->epilog( - __d('cake_console', 'Omitting all arguments and options will enter into an interactive mode.') - ); - - return $parser; - } - -} diff --git a/lib/Cake/Console/Command/Task/ViewTask.php b/lib/Cake/Console/Command/Task/ViewTask.php deleted file mode 100644 index fa7ddef448..0000000000 --- a/lib/Cake/Console/Command/Task/ViewTask.php +++ /dev/null @@ -1,477 +0,0 @@ -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 null; - } - 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 they 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 a 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)); - return $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 The template variables. - * @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, ' '); - return $this->_stop(); - } - $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 bool 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; - } - -/** - * Gets the option parser instance and configures it. - * - * @return ConsoleOptionParser - */ - public function getOptionParser() { - $parser = parent::getOptionParser(); - - $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 but create the filename after .') - ))->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('theme', array( - 'short' => 't', - 'help' => __d('cake_console', 'Theme to use when baking code.') - ))->addOption('connection', array( - 'short' => 'c', - 'help' => __d('cake_console', 'The connection the connected model is on.') - ))->addOption('force', array( - 'short' => 'f', - 'help' => __d('cake_console', 'Force overwriting existing files without prompting.') - ))->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.') - ); - - return $parser; - } - -/** - * Returns associations for controllers models. - * - * @param Model $model The Model instance. - * @return array associations - */ - protected function _associations(Model $model) { - $keys = array('belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany'); - $associations = array(); - - foreach ($keys as $type) { - foreach ($model->{$type} as $assocKey => $assocData) { - list(, $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/lib/Cake/Console/ConsoleInputOption.php b/lib/Cake/Console/ConsoleInputOption.php index 139c983539..13145eb472 100644 --- a/lib/Cake/Console/ConsoleInputOption.php +++ b/lib/Cake/Console/ConsoleInputOption.php @@ -90,7 +90,7 @@ public function __construct($name, $short = null, $help = '', $boolean = false, $this->_default = $default; $this->_choices = $choices; } - if (strlen($this->_short) > 1) { + if (!empty($this->_short) && strlen($this->_short) > 1) { throw new ConsoleException( __d('cake_console', 'Short option "%s" is invalid, short options must be one letter.', $this->_short) ); diff --git a/lib/Cake/Console/ConsoleOptionParser.php b/lib/Cake/Console/ConsoleOptionParser.php index f313c41c96..ac8b6e4027 100644 --- a/lib/Cake/Console/ConsoleOptionParser.php +++ b/lib/Cake/Console/ConsoleOptionParser.php @@ -76,6 +76,7 @@ * * @package Cake.Console */ +#[AllowDynamicProperties] class ConsoleOptionParser { /** diff --git a/lib/Cake/Console/HelpFormatter.php b/lib/Cake/Console/HelpFormatter.php index 0c4259aae3..dc884e6dd1 100644 --- a/lib/Cake/Console/HelpFormatter.php +++ b/lib/Cake/Console/HelpFormatter.php @@ -43,8 +43,9 @@ class HelpFormatter { * @var int */ protected $_maxOptions = 6; + private ConsoleOptionParser $_parser; -/** + /** * Build the help formatter for an OptionParser * * @param ConsoleOptionParser $parser The option parser help is being generated for. diff --git a/lib/Cake/Console/Shell.php b/lib/Cake/Console/Shell.php index f8365205fc..533158056b 100644 --- a/lib/Cake/Console/Shell.php +++ b/lib/Cake/Console/Shell.php @@ -376,7 +376,7 @@ public function hasMethod(?string $name = null) { * * With a string command: * - * `return $this->dispatchShell('schema create DbAcl');` + * `return $this->dispatchShell('schema create asdsad');` * * 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 @@ -851,7 +851,7 @@ protected function _checkUnitTest() { * @link https://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(ROOT, '', $file); $shortPath = str_replace('..' . DS, '', $shortPath); return str_replace(DS . DS, DS, $shortPath); } diff --git a/lib/Cake/Console/ShellDispatcher.php b/lib/Cake/Console/ShellDispatcher.php index 22a4e53f76..aa2793e803 100644 --- a/lib/Cake/Console/ShellDispatcher.php +++ b/lib/Cake/Console/ShellDispatcher.php @@ -292,7 +292,7 @@ public function parseParams($args) { $params = array_merge($defaults, array_intersect_key($this->params, $defaults)); $isWin = false; foreach ($defaults as $default => $value) { - if (strpos($params[$default], '\\') !== false) { + if (strpos((string)$params[$default], '\\') !== false) { $isWin = true; break; } diff --git a/lib/Cake/Console/Templates/skel/Config/Schema/db_acl.php b/lib/Cake/Console/Templates/skel/Config/Schema/db_acl.php deleted file mode 100644 index 12ad8ee98f..0000000000 --- a/lib/Cake/Console/Templates/skel/Config/Schema/db_acl.php +++ /dev/null @@ -1,80 +0,0 @@ - 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)) - ); - -/** - * ARO - Access Request Object - Something that wants something - */ - 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)) - ); - -/** - * Used by the Cake::Model:Permission class. - * Checks if the given $aro has access to action $action in $aco. - */ - 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/lib/Cake/Console/Templates/skel/Config/Schema/db_acl.sql b/lib/Cake/Console/Templates/skel/Config/Schema/db_acl.sql deleted file mode 100644 index cbb0cceced..0000000000 --- a/lib/Cake/Console/Templates/skel/Config/Schema/db_acl.sql +++ /dev/null @@ -1,52 +0,0 @@ -# $Id$ -# -# Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) -# -# Licensed under The MIT License -# For full copyright and license information, please see the LICENSE.txt -# Redistributions of files must retain the above copyright notice. -# MIT License (https://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) -); - -/* this indexes will improve acl perfomance */ -CREATE INDEX idx_acos_lft_rght ON `acos` (`lft`, `rght`); - -CREATE INDEX idx_acos_alias ON `acos` (`alias`); - -CREATE INDEX idx_aros_lft_rght ON `aros` (`lft`, `rght`); - -CREATE INDEX idx_aros_alias ON `aros` (`alias`); - -CREATE INDEX idx_aco_id ON `aros_acos` (`aco_id`); diff --git a/lib/Cake/Console/Templates/skel/Config/acl.ini.php b/lib/Cake/Console/Templates/skel/Config/acl.ini.php deleted file mode 100644 index 1f93158696..0000000000 --- a/lib/Cake/Console/Templates/skel/Config/acl.ini.php +++ /dev/null @@ -1,57 +0,0 @@ -; -;/** -; * ACL Configuration -; * -; * @link https://cakephp.org CakePHP(tm) Project -; * @package app.Config -; * @since CakePHP(tm) v 0.10.0.1076 -; */ - -; acl.ini.php - CakePHP 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 diff --git a/lib/Cake/Console/Templates/skel/Config/acl.php b/lib/Cake/Console/Templates/skel/Config/acl.php deleted file mode 100644 index 2fe93fea40..0000000000 --- a/lib/Cake/Console/Templates/skel/Config/acl.php +++ /dev/null @@ -1,124 +0,0 @@ -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/lib/Cake/Console/Templates/skel/Config/bootstrap.php b/lib/Cake/Console/Templates/skel/Config/bootstrap.php index 6d05aabbb6..f9c02289e3 100644 --- a/lib/Cake/Console/Templates/skel/Config/bootstrap.php +++ b/lib/Cake/Console/Templates/skel/Config/bootstrap.php @@ -28,7 +28,6 @@ * '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/'), diff --git a/lib/Cake/Console/Templates/skel/Config/core.php b/lib/Cake/Console/Templates/skel/Config/core.php index 864777666a..5cdec84a39 100644 --- a/lib/Cake/Console/Templates/skel/Config/core.php +++ b/lib/Cake/Console/Templates/skel/Config/core.php @@ -243,13 +243,6 @@ */ //Configure::write('Asset.filter.js', 'custom_javascript_output_filter.php'); -/** - * The class name 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. diff --git a/lib/Cake/Controller/Component/Acl/AclInterface.php b/lib/Cake/Controller/Component/Acl/AclInterface.php deleted file mode 100644 index 6d6324170b..0000000000 --- a/lib/Cake/Controller/Component/Acl/AclInterface.php +++ /dev/null @@ -1,73 +0,0 @@ -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 Component $component The AclComponent instance. - * @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 bool Success (true if ARO has access to action in ACO, false otherwise) - * @link https://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 int $value Value to indicate access type (1 to give access, -1 to deny, 0 to inherit) - * @return bool Success - * @link https://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 bool Success - * @link https://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 bool 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 bool 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 bool 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/lib/Cake/Controller/Component/Acl/IniAcl.php b/lib/Cake/Controller/Component/Acl/IniAcl.php deleted file mode 100644 index 9012cdb470..0000000000 --- a/lib/Cake/Controller/Component/Acl/IniAcl.php +++ /dev/null @@ -1,174 +0,0 @@ -config) { - $this->config = $this->readConfigFile(CONFIG . '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/lib/Cake/Controller/Component/Acl/PhpAcl.php b/lib/Cake/Controller/Component/Acl/PhpAcl.php deleted file mode 100644 index 04176763ae..0000000000 --- a/lib/Cake/Controller/Component/Acl/PhpAcl.php +++ /dev/null @@ -1,561 +0,0 @@ -options = array( - 'policy' => static::DENY, - 'config' => CONFIG . 'acl.php', - ); - } - -/** - * Initialize method - * - * @param AclComponent $Component Component instance - * @return void - */ - public function initialize(Component $Component) { - if (!empty($Component->settings['adapter'])) { - $this->options = $Component->settings['adapter'] + $this->options; - } - - 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 bool 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 bool 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 bool 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 bool 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 $node) { - foreach ($prioritizedAros as $aros) { - if (!empty($node['allow'])) { - $allow = $allow || count(array_intersect($node['allow'], $aros)); - } - - if (!empty($node['deny'])) { - $allow = $allow && !count(array_intersect($node['deny'], $aros)); - } - } - } - - 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( - '*' => '.*', - ); - -/** - * Constructor - * - * @param array $rules Rules 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 - * - * @param string $aco ACO string - * @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(static::$modifiers), array_values(static::$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 - * - * @param string $aro ARO string - * @param string $aco ACO string - * @param string $action Action string - * @param string $type access type - * @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 occurrences 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()) { - $this->_tree = array(); - - 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(); - -/** - * Constructor - * - * @param array $aro The aro data - * @param array $map The identifier mappings - * @param array $aliases The aliases to map. - */ - 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 static::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 = $alias + $this->aliases; - } - -/** - * 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/lib/Cake/Controller/Component/AclComponent.php b/lib/Cake/Controller/Component/AclComponent.php deleted file mode 100644 index c6f3ec79d5..0000000000 --- a/lib/Cake/Controller/Component/AclComponent.php +++ /dev/null @@ -1,180 +0,0 @@ -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|null 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 null; - } - 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 bool 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 bool 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 bool 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 bool 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 bool Success - * @deprecated 3.0.0 Will be removed in 3.0. - */ - public function grant($aro, $aco, $action = "*") { - trigger_error(__d('cake_dev', '%s is deprecated, use %s instead', 'AclComponent::grant()', 'allow()'), 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 bool Success - * @deprecated 3.0.0 Will be removed in 3.0. - */ - public function revoke($aro, $aco, $action = "*") { - trigger_error(__d('cake_dev', '%s is deprecated, use %s instead', 'AclComponent::revoke()', 'deny()'), E_USER_WARNING); - return $this->_Instance->deny($aro, $aco, $action); - } - -} diff --git a/lib/Cake/Controller/Component/Auth/ActionsAuthorize.php b/lib/Cake/Controller/Component/Auth/ActionsAuthorize.php deleted file mode 100644 index 965e5fbd7d..0000000000 --- a/lib/Cake/Controller/Component/Auth/ActionsAuthorize.php +++ /dev/null @@ -1,41 +0,0 @@ -_Collection->load('Acl'); - $user = array($this->settings['userModel'] => $user); - return $Acl->check($user, $this->action($request)); - } - -} diff --git a/lib/Cake/Controller/Component/Auth/CrudAuthorize.php b/lib/Cake/Controller/Component/Auth/CrudAuthorize.php deleted file mode 100644 index 6eb06f3336..0000000000 --- a/lib/Cake/Controller/Component/Auth/CrudAuthorize.php +++ /dev/null @@ -1,101 +0,0 @@ -_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 bool - */ - 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/lib/Cake/Controller/Controller.php b/lib/Cake/Controller/Controller.php index a0cc93b525..cfd8df494a 100644 --- a/lib/Cake/Controller/Controller.php +++ b/lib/Cake/Controller/Controller.php @@ -44,7 +44,6 @@ * using Router::connect(). * * @package Cake.Controller - * @property AclComponent $Acl * @property AuthComponent $Auth * @property CookieComponent $Cookie * @property EmailComponent $Email @@ -62,6 +61,7 @@ * @property string $webroot Webroot path segment for the request. * @link https://book.cakephp.org/2.0/en/controllers.html */ +#[AllowDynamicProperties] class Controller extends CakeObject implements CakeEventListener { /** @@ -192,7 +192,7 @@ class Controller extends CakeObject implements CakeEventListener { * Array containing the names of components this controller uses. Component names * should not contain the "Component" portion of the class name. * - * Example: `public $components = array('Session', 'RequestHandler', 'Acl');` + * Example: `public $components = array('Session', 'RequestHandler');` * * @var array * @link https://book.cakephp.org/2.0/en/controllers/components.html diff --git a/lib/Cake/Core/App.php b/lib/Cake/Core/App.php index 5aeac30243..2216ce6d32 100644 --- a/lib/Cake/Core/App.php +++ b/lib/Cake/Core/App.php @@ -848,9 +848,6 @@ protected static function _packageFormat() { '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 ), diff --git a/lib/Cake/Core/CakeObject.php b/lib/Cake/Core/CakeObject.php index 0a0f3ac16e..f71daa5f0b 100644 --- a/lib/Cake/Core/CakeObject.php +++ b/lib/Cake/Core/CakeObject.php @@ -27,6 +27,7 @@ * * @package Cake.Core */ +#[AllowDynamicProperties] class CakeObject { /** diff --git a/lib/Cake/Error/exceptions.php b/lib/Cake/Error/exceptions.php index 540453bbf8..432d9aa2fa 100644 --- a/lib/Cake/Error/exceptions.php +++ b/lib/Cake/Error/exceptions.php @@ -504,14 +504,6 @@ class MissingDispatcherFilterException extends CakeException { } -/** - * 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. diff --git a/lib/Cake/Event/CakeEvent.php b/lib/Cake/Event/CakeEvent.php index 4a23756efc..5710e9fb07 100644 --- a/lib/Cake/Event/CakeEvent.php +++ b/lib/Cake/Event/CakeEvent.php @@ -21,8 +21,33 @@ * * @package Cake.Event */ +#[AllowDynamicProperties] class CakeEvent { +/** + * PHP 8.2 deprecation notice: added to avoid `Creation of dynamic property ... is deprecated.` + * @var mixed|true + */ + public mixed $break; + +/** + * PHP 8.2 deprecation notice: added to avoid `Creation of dynamic property ... is deprecated.` + * @var mixed|true + */ + public mixed $modParams; + +/** + * PHP 8.2 deprecation notice: added to avoid `Creation of dynamic property ... is deprecated.` + * @var array|mixed + */ + public mixed $breakOn; + +/** + * PHP 8.2 deprecation notice: added to avoid `Creation of dynamic property ... is deprecated.` + * @var array|mixed + */ + public mixed $omitSubject; + /** * Name of the event * diff --git a/lib/Cake/I18n/I18n.php b/lib/Cake/I18n/I18n.php index 814c2cfe08..1c63db323b 100644 --- a/lib/Cake/I18n/I18n.php +++ b/lib/Cake/I18n/I18n.php @@ -232,7 +232,7 @@ public static function translate($singular, $plural = null, $domain = null, $cat $_this->domain = $domain . '_' . $_this->l10n->lang; if (!isset($_this->_domains[$domain][$_this->_lang])) { - $_this->_domains[$domain][$_this->_lang] = Cache::read($_this->domain, '_cake_core_'); + $_this->_domains[$domain][$_this->_lang] = Cache::read($_this->domain, '_cake_core_') ?: []; } if (!isset($_this->_domains[$domain][$_this->_lang][$_this->category])) { diff --git a/lib/Cake/Log/LogEngineCollection.php b/lib/Cake/Log/LogEngineCollection.php index f68a332084..248d9a35e3 100644 --- a/lib/Cake/Log/LogEngineCollection.php +++ b/lib/Cake/Log/LogEngineCollection.php @@ -23,6 +23,7 @@ * * @package Cake.Log */ +#[AllowDynamicProperties] class LogEngineCollection extends ObjectCollection { /** diff --git a/lib/Cake/Model/AclNode.php b/lib/Cake/Model/AclNode.php deleted file mode 100644 index 11c9a51016..0000000000 --- a/lib/Cake/Model/AclNode.php +++ /dev/null @@ -1,188 +0,0 @@ - array('type' => 'nested')); - -/** - * Constructor - * - * @param bool|int|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) { - $config = Configure::read('Acl.database'); - if (isset($config)) { - $this->useDbConfig = $config; - } - parent::__construct($id, $table, $ds); - } - -/** - * 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' => 'INNER', - 'conditions' => array("{$type}0.alias" => $start) - )), - 'order' => $db->name("{$type}.lft") . ' DESC' - ); - - $conditionsAfterJoin = array(); - - foreach ($path as $i => $alias) { - $j = $i - 1; - - $queryData['joins'][] = array( - 'table' => $table, - 'alias' => "{$type}{$i}", - 'type' => 'INNER', - 'conditions' => array( - "{$type}{$i}.alias" => $alias - ) - ); - - // it will be better if this conditions will performs after join operation - $conditionsAfterJoin[] = $db->name("{$type}{$j}.id") . ' = ' . $db->name("{$type}{$i}.parent_id"); - $conditionsAfterJoin[] = $db->name("{$type}{$i}.rght") . ' < ' . $db->name("{$type}{$j}.rght"); - $conditionsAfterJoin[] = $db->name("{$type}{$i}.lft") . ' > ' . $db->name("{$type}{$j}.lft"); - - $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")) - ); - } - $queryData['conditions'] = array_merge($queryData['conditions'], $conditionsAfterJoin); - $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) && $ref instanceof 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(, $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' => 'INNER', - '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/lib/Cake/Model/Aco.php b/lib/Cake/Model/Aco.php deleted file mode 100644 index 2a20d8e599..0000000000 --- a/lib/Cake/Model/Aco.php +++ /dev/null @@ -1,39 +0,0 @@ - array('with' => 'Permission')); -} diff --git a/lib/Cake/Model/AcoAction.php b/lib/Cake/Model/AcoAction.php deleted file mode 100644 index 20cfe27934..0000000000 --- a/lib/Cake/Model/AcoAction.php +++ /dev/null @@ -1,39 +0,0 @@ - array('with' => 'Permission')); -} diff --git a/lib/Cake/Model/Behavior/AclBehavior.php b/lib/Cake/Model/Behavior/AclBehavior.php deleted file mode 100644 index 45a3260994..0000000000 --- a/lib/Cake/Model/Behavior/AclBehavior.php +++ /dev/null @@ -1,144 +0,0 @@ - '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 Model using this behavior. - * @param array $config Configuration options. - * @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 %s not defined in %s', 'parentNode()', $model->alias), E_USER_WARNING); - } - } - -/** - * Retrieves the Aro/Aco node for this model - * - * @param Model $model Model using this behavior. - * @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 https://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 array(); - } - } - 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 Model using this behavior. - * @param bool $created True if this is a new record - * @param array $options Options passed from Model::save(). - * @return void - */ - public function afterSave(Model $model, $created, $options = array()) { - $types = $this->_typeMaps[$this->settings[$model->name]['type']]; - if (!is_array($types)) { - $types = array($types); - } - foreach ($types as $type) { - $parent = $model->parentNode($type); - 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 Model using this behavior. - * @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/lib/Cake/Model/Behavior/ContainableBehavior.php b/lib/Cake/Model/Behavior/ContainableBehavior.php index 57ae597dad..c1f8bc5489 100644 --- a/lib/Cake/Model/Behavior/ContainableBehavior.php +++ b/lib/Cake/Model/Behavior/ContainableBehavior.php @@ -370,6 +370,7 @@ public function containments(Model $Model, $contain, $containments = array(), $t */ public function fieldDependencies(Model $Model, $map, $fields = array()) { if ($fields === false) { + $fields = []; foreach ($map as $parent => $children) { foreach ($children as $type => $bindings) { foreach ($bindings as $dependency) { diff --git a/lib/Cake/Model/CakeSchema.php b/lib/Cake/Model/CakeSchema.php index f2cb4e73d2..ef55f60f02 100644 --- a/lib/Cake/Model/CakeSchema.php +++ b/lib/Cake/Model/CakeSchema.php @@ -85,7 +85,7 @@ public function __construct($options = array()) { $this->plugin = $options['plugin']; } - if (strtolower($this->name) === 'cake') { + if (!empty($this->name) && strtolower($this->name) === 'cake') { $this->name = 'App'; } diff --git a/lib/Cake/Model/Datasource/CakeSession.php b/lib/Cake/Model/Datasource/CakeSession.php index e67731429b..87fdb69838 100644 --- a/lib/Cake/Model/Datasource/CakeSession.php +++ b/lib/Cake/Model/Datasource/CakeSession.php @@ -200,7 +200,7 @@ protected static function _setPath($base = null) { */ protected static function _setHost($host) { static::$host = $host; - if (strpos(static::$host, ':') !== false) { + if (strpos((string) static::$host, ':') !== false) { static::$host = substr(static::$host, 0, strpos(static::$host, ':')); } } diff --git a/lib/Cake/Model/Datasource/Database/Mysql.php b/lib/Cake/Model/Datasource/Database/Mysql.php index fb8a3455e0..7661d89f39 100644 --- a/lib/Cake/Model/Datasource/Database/Mysql.php +++ b/lib/Cake/Model/Datasource/Database/Mysql.php @@ -838,7 +838,7 @@ public function column($real) { */ public function value($data, $column = null, $null = true) { $value = parent::value($data, $column, $null); - if (is_numeric($value) && substr($column, 0, 3) === 'set') { + if (is_numeric($value) && !empty($column) && substr($column, 0, 3) === 'set') { return $this->_connection->quote($value); } return $value; diff --git a/lib/Cake/Model/Datasource/Database/Sqlite.php b/lib/Cake/Model/Datasource/Database/Sqlite.php index 487868be4a..cfc95d454a 100644 --- a/lib/Cake/Model/Datasource/Database/Sqlite.php +++ b/lib/Cake/Model/Datasource/Database/Sqlite.php @@ -179,7 +179,7 @@ public function describe($model) { ); foreach ($result as $column) { - $default = ($column['dflt_value'] === 'NULL') ? null : trim($column['dflt_value'], "'"); + $default = ($column['dflt_value'] === 'NULL') ? null : trim((string) $column['dflt_value'], "'"); $fields[$column['name']] = array( 'type' => $this->column($column['type']), diff --git a/lib/Cake/Model/Model.php b/lib/Cake/Model/Model.php index 860ad5bdf1..702baca7b7 100644 --- a/lib/Cake/Model/Model.php +++ b/lib/Cake/Model/Model.php @@ -1228,6 +1228,11 @@ public function set($one, $two = null) { } if (!isset($this->data[$modelName])) { + + if ($this->data === false) { + $this->data = []; + } + $this->data[$modelName] = array(); } diff --git a/lib/Cake/Model/ModelValidator.php b/lib/Cake/Model/ModelValidator.php index 406c0816cc..ab988626c0 100644 --- a/lib/Cake/Model/ModelValidator.php +++ b/lib/Cake/Model/ModelValidator.php @@ -461,51 +461,51 @@ protected function _triggerBeforeValidate($options = array()) { /** * Returns whether a rule set is defined for a field or not * - * @param string $field name of the field to check + * @param string $offset name of the field to check * @return bool */ - public function offsetExists($field) { + public function offsetExists($offset): bool { $this->_parseRules(); - return isset($this->_fields[$field]); + return isset($this->_fields[$offset]); } /** * Returns the rule set for a field * - * @param string $field name of the field to check + * @param string $offset name of the field to check * @return CakeValidationSet */ - public function offsetGet($field) { + public function offsetGet($offset): mixed { $this->_parseRules(); - return $this->_fields[$field]; + return $this->_fields[$offset]; } /** * Sets the rule set for a field * - * @param string $field name of the field to set + * @param string $offset name of the field to set * @param array|CakeValidationSet $rules set of rules to apply to field * @return void */ - public function offsetSet($field, $rules) { + public function offsetSet($offset, $rules): void { $this->_parseRules(); if (!$rules instanceof CakeValidationSet) { - $rules = new CakeValidationSet($field, $rules); + $rules = new CakeValidationSet($offset, $rules); $methods = $this->getMethods(); $rules->setMethods($methods); } - $this->_fields[$field] = $rules; + $this->_fields[$offset] = $rules; } /** * Unsets the rule set for a field * - * @param string $field name of the field to unset + * @param string $offset name of the field to unset * @return void */ - public function offsetUnset($field) { + public function offsetUnset($offset): void { $this->_parseRules(); - unset($this->_fields[$field]); + unset($this->_fields[$offset]); } /** @@ -513,7 +513,8 @@ public function offsetUnset($field) { * * @return ArrayIterator */ - public function getIterator() { + public function getIterator(): Traversable + { $this->_parseRules(); return new ArrayIterator($this->_fields); } @@ -523,7 +524,7 @@ public function getIterator() { * * @return int */ - public function count() { + public function count(): int { $this->_parseRules(); return count($this->_fields); } diff --git a/lib/Cake/Model/Permission.php b/lib/Cake/Model/Permission.php deleted file mode 100644 index dc3dcf526a..0000000000 --- a/lib/Cake/Model/Permission.php +++ /dev/null @@ -1,259 +0,0 @@ -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 bool Success (true if ARO has access to action in ACO, false otherwise) - */ - public function check($aro, $aco, $action = '*') { - if (!$aro || !$aco) { - return false; - } - - $permKeys = $this->getAcoKeys($this->schema()); - $aroPath = $this->Aro->node($aro); - $acoPath = $this->Aco->node($aco); - - if (!$aroPath) { - $this->log(__d('cake_dev', - "%s - Failed ARO node lookup in permissions check. Node references:\nAro: %s\nAco: %s", - 'DbAcl::check()', - print_r($aro, true), - print_r($aco, true)), - E_USER_WARNING - ); - return false; - } - - if (!$acoPath) { - $this->log(__d('cake_dev', - "%s - Failed ACO node lookup in permissions check. Node references:\nAro: %s\nAco: %s", - 'DbAcl::check()', - print_r($aro, true), - print_r($aco, true)), - E_USER_WARNING - ); - return false; - } - - if ($action !== '*' && !in_array('_' . $action, $permKeys)) { - $this->log(__d('cake_dev', "ACO permissions key %s does not exist in %s", $action, 'DbAcl::check()'), E_USER_NOTICE); - return false; - } - - $acoIDs = Hash::extract($acoPath, '{n}.' . $this->Aco->alias . '.id'); - - $count = count($aroPath); - $inherited = array(); - 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; - } - $perms = Hash::extract($perms, '{n}.' . $this->alias); - foreach ($perms as $perm) { - if ($action === '*') { - if (empty($perm)) { - continue; - } - foreach ($permKeys as $key) { - if ($perm[$key] == -1 && !(isset($inherited[$key]) && $inherited[$key] == 1)) { - // Deny, but only if a child node didnt't explicitly allow - return false; - } elseif ($perm[$key] == 1) { - // Allow & inherit from parent nodes - $inherited[$key] = $perm[$key]; - } - } - } else { - switch ($perm['_' . $action]) { - case -1: - return false; - case 0: - break; - case 1: - return true; - } - } - } - - if ($action === '*' && count($inherited) === count($permKeys)) { - return true; - } - } - 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 *) Invalid permissions will result in an exception - * @param int $value Value to indicate access type (1 to give access, -1 to deny, 0 to inherit) - * @return bool Success - * @throws AclException on Invalid permission key. - */ - public function allow($aro, $aco, $actions = '*', $value = 1) { - $perms = $this->getAclLink($aro, $aco); - $permKeys = $this->getAcoKeys($this->schema()); - $save = array(); - - if (!$perms) { - $this->log(__d('cake_dev', '%s - Invalid node', 'DbAcl::allow()'), 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); - } - foreach ($actions as $action) { - if ($action[0] !== '_') { - $action = '_' . $action; - } - if (!in_array($action, $permKeys, true)) { - throw new AclException(__d('cake_dev', 'Invalid permission key "%s"', $action)); - } - $save[$action] = $value; - } - } - list($save['aro_id'], $save['aco_id']) = array($perms['aro'], $perms['aco']); - - if ($perms['link'] && !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/lib/Cake/Model/Validator/CakeValidationSet.php b/lib/Cake/Model/Validator/CakeValidationSet.php index eab540861f..d252cab8fe 100644 --- a/lib/Cake/Model/Validator/CakeValidationSet.php +++ b/lib/Cake/Model/Validator/CakeValidationSet.php @@ -307,21 +307,21 @@ protected function _translateArgs($args) { /** * Returns whether an index exists in the rule set * - * @param string $index name of the rule + * @param string $offset name of the rule * @return bool */ - public function offsetExists($index) { - return isset($this->_rules[$index]); + public function offsetExists($offset): bool { + return isset($this->_rules[$offset]); } /** * Returns a rule object by its index * - * @param string $index name of the rule + * @param string $offset name of the rule * @return CakeValidationRule */ - public function offsetGet($index) { - return $this->_rules[$index]; + public function offsetGet($offset): mixed { + return $this->_rules[$offset]; } /** @@ -330,23 +330,23 @@ public function offsetGet($index) { * This is a wrapper for ArrayAccess. Use setRule() directly for * chainable access. * - * @param string $index Name of the rule. - * @param CakeValidationRule|array $rule Rule to add to $index. + * @param string $offset Name of the rule. + * @param CakeValidationRule|array $value Rule to add to $index. * @return void * @see http://www.php.net/manual/en/arrayobject.offsetset.php */ - public function offsetSet($index, $rule) { - $this->setRule($index, $rule); + public function offsetSet($offset, $value): void { + $this->setRule($offset, $value); } /** * Unsets a validation rule * - * @param string $index name of the rule + * @param string $offset name of the rule * @return void */ - public function offsetUnset($index) { - unset($this->_rules[$index]); + public function offsetUnset($offset): void { + unset($this->_rules[$offset]); } /** diff --git a/lib/Cake/Network/CakeRequest.php b/lib/Cake/Network/CakeRequest.php index f375f60790..46cbae2aa6 100644 --- a/lib/Cake/Network/CakeRequest.php +++ b/lib/Cake/Network/CakeRequest.php @@ -228,7 +228,7 @@ protected function _processGet() { unset($query[$unsetUrl]); unset($query[$this->base . $unsetUrl]); if (strpos($this->url, '?') !== false) { - list($this->url, $querystr) = explode('?', $this->url); + [$this->url, $querystr] = explode('?', $this->url); parse_str($querystr, $queryArgs); $query += $queryArgs; } @@ -275,7 +275,7 @@ protected function _url() { $uri = substr($uri, strlen($base)); } if (strpos($uri, '?') !== false) { - list($uri) = explode('?', $uri, 2); + [$uri] = explode('?', $uri, 2); } if (empty($uri) || $uri === '/' || $uri === '//' || $uri === '/index.php') { $uri = '/'; @@ -919,7 +919,7 @@ public static function acceptLanguage($language = null) { */ protected static function _parseAcceptWithQualifier($header) { $accept = array(); - $header = explode(',', $header); + $header = explode(',', (string) $header); foreach (array_filter($header) as $value) { $prefValue = '1.0'; $value = trim($value); @@ -1043,7 +1043,8 @@ public function input($callback = null) { * @param string $input A string to replace original parsed data from input() * @return void */ - public function setInput($input) { + public function setInput($input): void + { $this->_input = $input; } @@ -1064,7 +1065,8 @@ public function setInput($input) { * @return bool true * @throws MethodNotAllowedException */ - public function allowMethod($methods) { + public function allowMethod($methods): bool + { if (!is_array($methods)) { $methods = func_get_args(); } @@ -1088,7 +1090,8 @@ public function allowMethod($methods) { * @see CakeRequest::allowMethod() * @deprecated 3.0.0 Since 2.5, use CakeRequest::allowMethod() instead. */ - public function onlyAllow($methods) { + public function onlyAllow($methods): bool + { if (!is_array($methods)) { $methods = func_get_args(); } @@ -1100,9 +1103,10 @@ public function onlyAllow($methods) { * * @return string contents of php://input */ - protected function _readInput() { + protected function _readInput(): string + { if (empty($this->_input)) { - $fh = fopen('php://input', 'r'); + $fh = fopen('php://input', 'rb'); $content = stream_get_contents($fh); fclose($fh); $this->_input = $content; @@ -1113,17 +1117,18 @@ protected function _readInput() { /** * Array access read implementation * - * @param mixed $name Name of the key being accessed. + * @param mixed $offset Name of the key being accessed. * @return mixed */ - public function offsetGet( $name) { - if (isset($this->params[$name])) { - return $this->params[$name]; + public function offsetGet(mixed $offset): mixed + { + if (isset($this->params[$offset])) { + return $this->params[$offset]; } - if ($name === 'url') { + if ($offset === 'url') { return $this->query; } - if ($name === 'data') { + if ($offset === 'data') { return $this->data; } return null; @@ -1132,35 +1137,35 @@ public function offsetGet( $name) { /** * Array access write implementation * - * @param string $name Name of the key being written + * @param string $offset Name of the key being written * @param mixed $value The value being written. * @return void */ - public function offsetSet($name, $value) { - $this->params[$name] = $value; + public function offsetSet($offset, mixed $value): void { + $this->params[$offset] = $value; } /** * Array access isset() implementation * - * @param string $name thing to check. + * @param string $offset thing to check. * @return bool */ - public function offsetExists($name) { - if ($name === 'url' || $name === 'data') { + public function offsetExists(mixed $offset): bool { + if ($offset === 'url' || $offset === 'data') { return true; } - return isset($this->params[$name]); - } + return isset($this->params[$offset]); + } -/** + /** * Array access unset() implementation * - * @param string $name Name to unset. + * @param string $offset Name to unset. * @return void */ - public function offsetUnset($name) { - unset($this->params[$name]); + public function offsetUnset($offset): void { + unset($this->params[$offset]); } } diff --git a/lib/Cake/Test/Case/Cache/Engine/MemcacheEngineTest.php b/lib/Cake/Test/Case/Cache/Engine/MemcacheEngineTest.php deleted file mode 100644 index ae8a1489b3..0000000000 --- a/lib/Cake/Test/Case/Cache/Engine/MemcacheEngineTest.php +++ /dev/null @@ -1,516 +0,0 @@ - - * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) - * - * Licensed under The MIT License - * For full copyright and license information, please see the LICENSE.txt - * Redistributions of files must retain the above copyright notice - * - * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) - * @link https://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 https://opensource.org/licenses/mit-license.php MIT License - */ - -App::uses('Cache', 'Cache'); -App::uses('MemcacheEngine', 'Cache/Engine'); - -/** - * TestMemcacheEngine - * - * @package Cake.Test.Case.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() : void { - 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() : void { - 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', - '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); - //@codingStandardsIgnoreStart - if (!@$Memcache->connect($host, $port)) { - $available = false; - } - //@codingStandardsIgnoreEnd - } - - $this->skipIf(!$available, 'Need memcache servers at ' . implode(', ', $servers) . ' to run this test.'); - - $Memcache = new MemcacheEngine(); - $Memcache->init(array('engine' => 'Memcache', 'servers' => $servers)); - - $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 domain starts with u - * - * @return void - */ - public function testParseServerStringWithU() { - $Memcached = new TestMemcachedEngine(); - $result = $Memcached->parseServerString('udomain.net:13211'); - $this->assertEquals(array('udomain.net', '13211'), $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(3); - $result = Cache::read('other_test', 'memcache'); - $this->assertFalse($result); - - Cache::config('memcache', array('duration' => '+1 second')); - - $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'); - - // Wait until the written key can be retrieved with Memcache::getExtendedStats(), as there may be a delay. - sleep(1); - - $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', array('set')); - $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')); - } - -/** - * Test that failed add write return false. - * - * @return void - */ - public function testAdd() { - Cache::delete('test_add_key', 'memcache'); - - $result = Cache::add('test_add_key', 'test data', 'memcache'); - $this->assertTrue($result); - - $expected = 'test data'; - $result = Cache::read('test_add_key', 'memcache'); - $this->assertEquals($expected, $result); - - $result = Cache::add('test_add_key', 'test data 2', 'memcache'); - $this->assertFalse($result); - } -} diff --git a/lib/Cake/Test/Case/Cache/Engine/RedisEngineTest.php b/lib/Cake/Test/Case/Cache/Engine/RedisEngineTest.php deleted file mode 100644 index 00c5ffb3ea..0000000000 --- a/lib/Cake/Test/Case/Cache/Engine/RedisEngineTest.php +++ /dev/null @@ -1,425 +0,0 @@ - - * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) - * - * Licensed under The MIT License - * For full copyright and license information, please see the LICENSE.txt - * Redistributions of files must retain the above copyright notice - * - * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) - * @link https://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests - * @package Cake.Test.Case.Cache.Engine - * @since CakePHP(tm) v 2.2 - * @license https://opensource.org/licenses/mit-license.php MIT License - */ - -App::uses('Cache', 'Cache'); -App::uses('RedisEngine', 'Cache/Engine'); - -/** - * RedisEngineTest class - * - * @package Cake.Test.Case.Cache.Engine - */ -class RedisEngineTest extends CakeTestCase { - -/** - * setUp method - * - * @return void - */ - public function setUp() : void { - parent::setUp(); - $this->skipIf(!class_exists('Redis'), 'Redis is not installed or configured properly.'); - - $this->_cacheDisable = Configure::read('Cache.disable'); - Configure::write('Cache.disable', false); - - // @codingStandardsIgnoreStart - $socket = @fsockopen('127.0.0.1', 6379, $errno, $errstr, 1); - // @codingStandardsIgnoreEnd - $this->skipIf(!$socket, 'Redis is not running.'); - fclose($socket); - - Cache::config('redis', array( - 'engine' => 'Redis', - 'prefix' => 'cake_', - 'duration' => 3600 - )); - } - -/** - * tearDown method - * - * @return void - */ - public function tearDown() : void { - parent::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, - 'password' => false, - 'database' => 0, - 'unix_socket' => false, - ); - $this->assertEquals($expecting, $settings); - } - -/** - * testConnect method - * - * @return void - */ - public function testConnect() { - $Redis = new RedisEngine(); - $this->assertTrue($Redis->init(Cache::settings('redis'))); - } - -/** - * testMultiDatabaseOperations method - * - * @return void - */ - public function testMultiDatabaseOperations() { - Cache::config('redisdb0', array( - 'engine' => 'Redis', - 'prefix' => 'cake2_', - 'duration' => 3600, - 'persistent' => false, - )); - - Cache::config('redisdb1', array( - 'engine' => 'Redis', - 'database' => 1, - 'prefix' => 'cake2_', - 'duration' => 3600, - 'persistent' => false, - )); - - $result = Cache::write('save_in_0', true, 'redisdb0'); - $exist = Cache::read('save_in_0', 'redisdb0'); - $this->assertTrue($result); - $this->assertTrue($exist); - - $result = Cache::write('save_in_1', true, 'redisdb1'); - $this->assertTrue($result); - $exist = Cache::read('save_in_0', 'redisdb1'); - $this->assertFalse($exist); - $exist = Cache::read('save_in_1', 'redisdb1'); - $this->assertTrue($exist); - - Cache::delete('save_in_0', 'redisdb0'); - $exist = Cache::read('save_in_0', 'redisdb0'); - $this->assertFalse($exist); - - Cache::delete('save_in_1', 'redisdb1'); - $exist = Cache::read('save_in_1', 'redisdb1'); - $this->assertFalse($exist); - - Cache::drop('redisdb0'); - Cache::drop('redisdb1'); - } - -/** - * test write numbers method - * - * @return void - */ - public function testWriteNumbers() { - $result = Cache::write('test-counter', 1, 'redis'); - $this->assertSame(1, Cache::read('test-counter', 'redis')); - - $result = Cache::write('test-counter', 0, 'redis'); - $this->assertSame(0, Cache::read('test-counter', 'redis')); - - $result = Cache::write('test-counter', -1, 'redis'); - $this->assertSame(-1, Cache::read('test-counter', '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')); - } - -/** - * Test add method. - * - * @return void - */ - public function testAdd() { - Cache::delete('test_add_key', 'redis'); - - $result = Cache::add('test_add_key', 'test data', 'redis'); - $this->assertTrue($result); - - $expected = 'test data'; - $result = Cache::read('test_add_key', 'redis'); - $this->assertEquals($expected, $result); - - $result = Cache::add('test_add_key', 'test data 2', 'redis'); - $this->assertFalse($result); - } -} diff --git a/lib/Cake/Test/Case/Cache/Engine/WincacheEngineTest.php b/lib/Cake/Test/Case/Cache/Engine/WincacheEngineTest.php deleted file mode 100644 index ba4b6da18c..0000000000 --- a/lib/Cake/Test/Case/Cache/Engine/WincacheEngineTest.php +++ /dev/null @@ -1,281 +0,0 @@ - - * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) - * - * Licensed under The MIT License - * For full copyright and license information, please see the LICENSE.txt - * Redistributions of files must retain the above copyright notice - * - * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) - * @link https://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 https://opensource.org/licenses/mit-license.php MIT License - */ - -App::uses('Cache', 'Cache'); - -/** - * WincacheEngineTest class - * - * @package Cake.Test.Case.Cache.Engine - */ -class WincacheEngineTest extends CakeTestCase { - -/** - * setUp method - * - * @return void - */ - public function setUp() : void { - 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() : void { - 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')); - } - -/** - * Test that failed add write return false. - * - * @return void - */ - public function testAdd() { - Cache::delete('test_add_key', 'wincache'); - - $result = Cache::add('test_add_key', 'test data', 'wincache'); - $this->assertTrue($result); - - $expected = 'test data'; - $result = Cache::read('test_add_key', 'wincache'); - $this->assertEquals($expected, $result); - - $result = Cache::add('test_add_key', 'test data 2', 'wincache'); - $this->assertFalse($result); - } -} diff --git a/lib/Cake/Test/Case/Configure/IniReaderTest.php b/lib/Cake/Test/Case/Configure/IniReaderTest.php index 2644392337..7ee2855484 100644 --- a/lib/Cake/Test/Case/Configure/IniReaderTest.php +++ b/lib/Cake/Test/Case/Configure/IniReaderTest.php @@ -55,20 +55,6 @@ public function setUp() : void { $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'); - - $this->assertTrue(isset($config['admin'])); - $this->assertTrue(isset($config['paul']['groups'])); - $this->assertEquals('ads', $config['admin']['deny']); - } - /** * Test reading files. * @@ -83,33 +69,6 @@ public function testRead() { $this->assertTrue($config['bools']['test_on']); } -/** - * No other sections should exist. - * - * @return void - */ - public function testReadOnlyOneSection() { - $reader = new IniReader($this->path, 'admin'); - $config = $reader->read('acl.ini'); - - $this->assertTrue(isset($config['groups'])); - $this->assertEquals('administrators', $config['groups']); - } - -/** - * Test reading acl.ini.php. - * - * @return void - */ - public function testReadSpecialAclIniPhp() { - $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']); - } - /** * Test without section. * @@ -230,25 +189,6 @@ public function testReadPluginValue() { CakePlugin::unload(); } -/** - * Test reading acl.ini.php from plugins. - * - * @return void - */ - public function testReadPluginSpecialAclIniPhpValue() { - App::build(array( - 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS) - ), App::RESET); - CakePlugin::load('TestPlugin'); - $reader = new IniReader($this->path); - $result = $reader->read('TestPlugin.acl.ini.php'); - - $this->assertTrue(isset($result['admin'])); - $this->assertTrue(isset($result['paul']['groups'])); - $this->assertEquals('ads', $result['admin']['deny']); - CakePlugin::unload(); - } - /** * Test dump method. * diff --git a/lib/Cake/Test/Case/Console/Command/AclShellTest.php b/lib/Cake/Test/Case/Console/Command/AclShellTest.php deleted file mode 100644 index 842e7ddf39..0000000000 --- a/lib/Cake/Test/Case/Console/Command/AclShellTest.php +++ /dev/null @@ -1,311 +0,0 @@ -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'); - $this->assertEquals($expected, $result); - - $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("New Aro 'User.1' created.", 2); - $this->Task->expects($this->at(1))->method('out')->with("New Aro 'User.3' created.", 2); - $this->Task->expects($this->at(2))->method('out')->with("New Aro '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("Aro deleted.", 2); - $this->Task->delete(); - - $Aro = ClassRegistry::init('Aro'); - $result = $Aro->findById(3); - $this->assertSame(array(), $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', 'delete'); - $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/lib/Cake/Test/Case/Console/Command/BakeShellTest.php b/lib/Cake/Test/Case/Console/Command/BakeShellTest.php deleted file mode 100644 index 060d6217e5..0000000000 --- a/lib/Cake/Test/Case/Console/Command/BakeShellTest.php +++ /dev/null @@ -1,119 +0,0 @@ -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() : void { - 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('Bake All complete'); - - $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/lib/Cake/Test/Case/Console/Command/CommandListShellTest.php b/lib/Cake/Test/Case/Console/Command/CommandListShellTest.php index 2032af3f62..d6cb8a7b64 100644 --- a/lib/Cake/Test/Case/Console/Command/CommandListShellTest.php +++ b/lib/Cake/Test/Case/Console/Command/CommandListShellTest.php @@ -103,7 +103,7 @@ public function testMain() { $expected = "/\[.*TestPluginTwo.*\] example, welcome/"; $this->assertMatchesRegularExpression($expected, $output); - $expected = "/\[.*CORE.*\] acl, api, bake, command_list, completion, console, i18n, schema, server, test, testsuite, upgrade/"; + $expected = "/\[.*CORE.*\] api, command_list, completion, console, i18n, test, testsuite, upgrade/"; $this->assertMatchesRegularExpression($expected, $output); $expected = "/\[.*app.*\] sample/"; diff --git a/lib/Cake/Test/Case/Console/Command/CompletionShellTest.php b/lib/Cake/Test/Case/Console/Command/CompletionShellTest.php index 427066a7a3..4c2ae3c218 100644 --- a/lib/Cake/Test/Case/Console/Command/CompletionShellTest.php +++ b/lib/Cake/Test/Case/Console/Command/CompletionShellTest.php @@ -125,7 +125,7 @@ public function testCommands() { $this->Shell->runCommand('commands', array()); $output = $this->Shell->stdout->output; - $expected = "TestPlugin.example TestPlugin.test_plugin TestPluginTwo.example TestPluginTwo.welcome acl api bake command_list completion console i18n schema server test testsuite upgrade sample\n"; + $expected = "TestPlugin.example TestPlugin.test_plugin TestPluginTwo.example TestPluginTwo.welcome api command_list completion console i18n test testsuite upgrade sample\n"; $this->assertEquals($expected, $output); } diff --git a/lib/Cake/Test/Case/Console/Command/SchemaShellTest.php b/lib/Cake/Test/Case/Console/Command/SchemaShellTest.php deleted file mode 100644 index 2c3a07de23..0000000000 --- a/lib/Cake/Test/Case/Console/Command/SchemaShellTest.php +++ /dev/null @@ -1,698 +0,0 @@ - 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)), - ); - - public $newone = array( - 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'), - 'testit' => array('type' => 'string', 'null' => false, 'default' => 'Title'), - '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', 'core.aco', 'core.aro', 'core.aros_aco', - ); - -/** - * setUp method - * - * @return void - */ - public function setUp() : void { - 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() : void { - 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->assertInstanceOf('CakeSchema', $this->Shell->Schema); - $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(CONFIG . '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 = CONFIG . '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->assertMatchesRegularExpression('/DROP TABLE/', $contents); - $this->assertMatchesRegularExpression('/CREATE TABLE.*?i18n/', $contents); - $this->assertMatchesRegularExpression('/id/', $contents); - $this->assertMatchesRegularExpression('/model/', $contents); - $this->assertMatchesRegularExpression('/field/', $contents); - $this->assertMatchesRegularExpression('/locale/', $contents); - $this->assertMatchesRegularExpression('/foreign_key/', $contents); - $this->assertMatchesRegularExpression('/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->assertMatchesRegularExpression('/CREATE TABLE.*?test_plugin_acos/', $contents); - $this->assertMatchesRegularExpression('/id/', $contents); - $this->assertMatchesRegularExpression('/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'); - - $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\RegularExpression('/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->assertMatchesRegularExpression('/class TestPluginSchema/', $contents); - $this->assertMatchesRegularExpression('/public \$posts/', $contents); - $this->assertMatchesRegularExpression('/public \$auth_users/', $contents); - $this->assertMatchesRegularExpression('/public \$authors/', $contents); - $this->assertMatchesRegularExpression('/public \$test_plugin_comments/', $contents); - $this->assertDoesNotMatchRegularExpression('/public \$users/', $contents); - $this->assertDoesNotMatchRegularExpression('/public \$articles/', $contents); - CakePlugin::unload(); - } - -/** - * test generate with specific models - * - * @return void - */ - public function testGenerateModels() { - 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', - 'models' => 'TestPluginComment', - 'force' => false, - 'overwrite' => true - ); - $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->assertMatchesRegularExpression('/class TestPluginSchema/', $contents); - $this->assertMatchesRegularExpression('/public \$test_plugin_comments/', $contents); - $this->assertDoesNotMatchRegularExpression('/public \$authors/', $contents); - $this->assertDoesNotMatchRegularExpression('/public \$auth_users/', $contents); - $this->assertDoesNotMatchRegularExpression('/public \$posts/', $contents); - CakePlugin::unload(); - } - -/** - * test generate with excluded tables - * - * @return void - */ - public function testGenerateExclude() { - Configure::write('Acl.database', 'test'); - $this->db->cacheSources = false; - $this->Shell->params = array( - 'connection' => 'test', - 'force' => false, - 'models' => 'Aro, Aco, Permission', - 'overwrite' => true, - 'exclude' => 'acos, aros', - ); - $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->assertStringNotContainsString('public $acos = array(', $contents); - $this->assertStringNotContainsString('public $aros = array(', $contents); - $this->assertStringContainsString('public $aros_acos = array(', $contents); - } - -/** - * Test schema run create with --yes option - * - * @return void - */ - public function testCreateOptionYes() { - $this->Shell = $this->getMock( - 'SchemaShell', - array('in', 'out', 'hr', 'createFile', 'error', 'err', '_stop', '_run'), - array(&$this->Dispatcher) - ); - - $this->Shell->params = array( - 'connection' => 'test', - 'yes' => true, - ); - $this->Shell->args = array('i18n'); - $this->Shell->expects($this->never())->method('in'); - $this->Shell->expects($this->exactly(2))->method('_run'); - $this->Shell->startup(); - $this->Shell->create(); - } - -/** - * 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('i18n', $sources)) { - $this->markTestSkipped('i18n table already exists, cannot try to create it again.'); - } - $this->Shell->params = array( - 'connection' => 'test', - 'name' => 'I18n', - 'path' => CONFIG . 'Schema' - ); - $this->Shell->args = array('I18n', '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), 'i18n should be present.'); - - $schema = new I18nSchema(); - $db->execute($db->dropSchema($schema, 'i18n')); - } - -/** - * 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 run update with a table arg. and checks that a CREATE statement is issued - * table creation - * @return void - */ - public function testUpdateWithTableCreate() { - $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', 'newone'); - $this->Shell->startup(); - $this->Shell->expects($this->any()) - ->method('in') - ->will($this->returnValue('y')); - $this->Shell->expects($this->once()) - ->method('_run') - ->with($this->arrayHasKey('newone'), 'update', $this->isInstanceOf('CakeSchema')); - - $this->Shell->update(); - } - -/** - * test run update with --yes option - * - * @return void - */ - public function testUpdateWithOptionYes() { - $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, - 'yes' => true, - ); - $this->Shell->args = array('SchemaShellTest', 'articles'); - $this->Shell->startup(); - $this->Shell->expects($this->never())->method('in'); - $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 underscored names also result in CamelCased class names - * - * @return void - */ - public function testName() { - App::build(array( - 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS) - )); - CakePlugin::load('TestPlugin'); - $this->Shell->params = array( - 'plugin' => 'TestPlugin', - 'connection' => 'test', - 'name' => 'custom_names', - 'force' => false, - 'overwrite' => true, - ); - $this->Shell->startup(); - if (file_exists($this->Shell->Schema->path . DS . 'custom_names.php')) { - unlink($this->Shell->Schema->path . DS . 'custom_names.php'); - } - $this->Shell->generate(); - - $contents = file_get_contents($this->Shell->Schema->path . DS . 'custom_names.php'); - $this->assertMatchesRegularExpression('/class CustomNamesSchema/', $contents); - unlink($this->Shell->Schema->path . DS . 'custom_names.php'); - CakePlugin::unload(); - } - -/** - * test that passing name and file creates the passed filename with the - * passed class name - * - * @return void - */ - public function testNameAndFile() { - App::build(array( - 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS) - )); - CakePlugin::load('TestPlugin'); - $this->Shell->params = array( - 'plugin' => 'TestPlugin', - 'connection' => 'test', - 'name' => 'custom_name', - 'file' => 'other_name', - 'force' => false, - 'overwrite' => true, - ); - $this->Shell->startup(); - $file = $this->Shell->Schema->path . DS . 'other_name.php'; - if (file_exists($file)) { - unlink($file); - } - $this->Shell->generate(); - - $this->assertFileExists($file); - $contents = file_get_contents($file); - $this->assertMatchesRegularExpression('/class CustomNameSchema/', $contents); - - if (file_exists($file)) { - unlink($file); - } - 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/lib/Cake/Test/Case/Console/Command/Task/CommandTaskTest.php b/lib/Cake/Test/Case/Console/Command/Task/CommandTaskTest.php index 5dbc7a59de..043e2482fd 100644 --- a/lib/Cake/Test/Case/Console/Command/Task/CommandTaskTest.php +++ b/lib/Cake/Test/Case/Console/Command/Task/CommandTaskTest.php @@ -71,15 +71,11 @@ public function testGetShellList() { $expected = array( 'CORE' => array( - 'acl', 'api', - 'bake', 'command_list', 'completion', 'console', 'i18n', - 'schema', - 'server', 'test', 'testsuite', 'upgrade' @@ -112,15 +108,11 @@ public function testCommands() { 'TestPlugin.test_plugin', 'TestPluginTwo.example', 'TestPluginTwo.welcome', - 'acl', 'api', - 'bake', 'command_list', 'completion', 'console', 'i18n', - 'schema', - 'server', 'test', 'testsuite', 'upgrade', @@ -135,22 +127,12 @@ public function testCommands() { * @return void */ public function testSubCommands() { - $result = $this->CommandTask->subCommands('acl'); + $result = $this->CommandTask->subCommands('i18n'); $expected = array( - 'check', - 'create', - 'db_config', - 'delete', - 'deny', - 'getPath', - 'grant', - 'inherit', - 'initdb', - 'nodeExists', - 'parseIdentifier', - 'setParent', - 'view' + 'db_config', + 'extract', + 'initdb', ); $this->assertEquals($expected, $result); } @@ -173,8 +155,8 @@ public function testSubCommandsUnknownCommand() { * @return void */ public function testGetShell() { - $result = $this->CommandTask->getShell('acl'); - $this->assertInstanceOf('AclShell', $result); + $result = $this->CommandTask->getShell('i18n'); + $this->assertInstanceOf('I18nShell', $result); } /** diff --git a/lib/Cake/Test/Case/Console/Command/Task/ControllerTaskTest.php b/lib/Cake/Test/Case/Console/Command/Task/ControllerTaskTest.php deleted file mode 100644 index e9fbc57a67..0000000000 --- a/lib/Cake/Test/Case/Console/Command/Task/ControllerTaskTest.php +++ /dev/null @@ -1,618 +0,0 @@ -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)); - - if (!defined('ARTICLE_MODEL_CREATED')) { - $this->markTestSkipped('Could not run as an Article, Tag or Comment model was already loaded.'); - } - } - -/** - * tearDown method - * - * @return void - */ - public function tearDown() : void { - 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(2))->method('out')->with(' 1. BakeArticles'); - $this->Task->expects($this->at(3))->method('out')->with(' 2. BakeArticlesBakeTags'); - $this->Task->expects($this->at(4))->method('out')->with(' 3. BakeComments'); - $this->Task->expects($this->at(5))->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->assertSame(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(' Text, Number, CustomOne ')); - $result = $this->Task->doHelpers(); - $expected = array('Text', 'Number', '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(' Text, Number, CustomOne, , ')); - $result = $this->Task->doHelpers(); - $expected = array('Text', 'Number', '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->assertSame(array('Paginator'), $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('Paginator', '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('Paginator', 'RequestHandler', 'Security'); - $this->assertEquals($expected, $result); - } - -/** - * test Confirming controller user interaction - * - * @return void - */ - public function testConfirmController() { - $controller = 'Posts'; - $scaffold = false; - $helpers = array('Js', '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\tJs, 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('Js', 'Time'); - $components = array('Acl', 'Auth'); - $this->Task->expects($this->any())->method('createFile')->will($this->returnValue(true)); - - $result = $this->Task->bake('Articles', null, $helpers, $components); - $expected = file_get_contents(CAKE . 'Test' . DS . 'bake_compare' . DS . 'Controller' . DS . 'NoActions.ctp'); - $this->assertTextEquals($expected, $result); - - $result = $this->Task->bake('Articles', null, array(), array()); - $expected = file_get_contents(CAKE . 'Test' . DS . 'bake_compare' . DS . 'Controller' . DS . 'NoHelpersOrComponents.ctp'); - $this->assertTextEquals($expected, $result); - - $result = $this->Task->bake('Articles', 'scaffold', $helpers, $components); - $expected = file_get_contents(CAKE . 'Test' . DS . 'bake_compare' . DS . 'Controller' . DS . 'Scaffold.ctp'); - $this->assertTextEquals($expected, $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->assertStringContainsString("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() { - $result = $this->Task->bakeActions('BakeArticles', null, true); - $expected = file_get_contents(CAKE . 'Test' . DS . 'bake_compare' . DS . 'Controller' . DS . 'ActionsUsingSessions.ctp'); - $this->assertTextEquals($expected, $result); - - $result = $this->Task->bakeActions('BakeArticles', 'admin_', true); - $this->assertStringContainsString('function admin_index() {', $result); - $this->assertStringContainsString('function admin_add()', $result); - $this->assertStringContainsString('function admin_view($id = null)', $result); - $this->assertStringContainsString('function admin_edit($id = null)', $result); - $this->assertStringContainsString('function admin_delete($id = null)', $result); - } - -/** - * Test baking with Controller::flash() or no sessions. - * - * @return void - */ - public function testBakeActionsWithNoSessions() { - $result = $this->Task->bakeActions('BakeArticles', null, false); - $expected = file_get_contents(CAKE . 'Test' . DS . 'bake_compare' . DS . 'Controller' . DS . 'ActionsWithNoSessions.ctp'); - $this->assertTextEquals($expected, $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->assertMatchesRegularExpression('/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.'); - } - - $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 execute() with all and --admin - * - * @return void - */ - public function testExecuteIntoAllAdmin() { - $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->params['admin'] = true; - - $this->Task->Project->expects($this->any()) - ->method('getPrefix') - ->will($this->returnValue('admin_')); - $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('function admin_index') - )->will($this->returnValue(true)); - - $this->Task->execute(); - } - -/** - * test that `cake bake controller foos` works. - * - * @return void - */ - public function testExecuteWithController() { - $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) { - $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() { - $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\LogicalNot($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() { - $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() { - $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/lib/Cake/Test/Case/Console/Command/Task/DbConfigTaskTest.php b/lib/Cake/Test/Case/Console/Command/Task/DbConfigTaskTest.php deleted file mode 100644 index 2e1ebe8611..0000000000 --- a/lib/Cake/Test/Case/Console/Command/Task/DbConfigTaskTest.php +++ /dev/null @@ -1,132 +0,0 @@ -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 = CONFIG; - } - -/** - * tearDown method - * - * @return void - */ - public function tearDown() : void { - 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(CONFIG, $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')); //persistent - $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 - ) - )); - - $this->Task->execute(); - } -} diff --git a/lib/Cake/Test/Case/Console/Command/Task/FixtureTaskTest.php b/lib/Cake/Test/Case/Console/Command/Task/FixtureTaskTest.php deleted file mode 100644 index 9c5aba39e5..0000000000 --- a/lib/Cake/Test/Case/Console/Command/Task/FixtureTaskTest.php +++ /dev/null @@ -1,532 +0,0 @@ -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() : void { - 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->interactive = true; - $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->interactive = true; - $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 with overwriting command line options. - * - * @return void - */ - public function testImportOptionsWithCommandLineOptions() { - $this->Task->params = array('schema' => true, 'records' => true); - - $result = $this->Task->importOptions('Article'); - $expected = array('schema' => 'Article', 'fromTable' => true); - $this->assertEquals($expected, $result); - } - -/** - * test importOptions with overwriting CLI options - * - * @return void - */ - public function testImportOptionsWithCommandLineOptionsPlugin() { - $this->Task->params = array('schema' => true, 'records' => true, 'plugin' => 'TestPlugin'); - - $result = $this->Task->importOptions('Article'); - $expected = array('schema' => 'TestPlugin.Article', 'fromTable' => true); - $this->assertEquals($expected, $result); - } - -/** - * test importOptions with schema. - * - * @return void - */ - public function testImportOptionsWithSchema() { - $this->Task->interactive = true; - $this->Task->params = array('schema' => true); - $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('n')); - $this->Task->expects($this->at(1))->method('in')->will($this->returnValue('n')); - - $result = $this->Task->importOptions('Article'); - $expected = array('schema' => 'Article'); - $this->assertEquals($expected, $result); - } - -/** - * test importOptions with records. - * - * @return void - */ - public function testImportOptionsWithRecords() { - $this->Task->interactive = true; - $this->Task->params = array('records' => true); - $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('n')); - - $result = $this->Task->importOptions('Article'); - $expected = array('fromTable' => true); - $this->assertEquals($expected, $result); - } - -/** - * test importOptions choosing from Table. - * - * @return void - */ - public function testImportOptionsTable() { - $this->Task->interactive = true; - $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->expects($this->at(1))->method('in') - ->with($this->anything(), $this->anything(), '3') - ->will($this->returnValue('2')); - - $this->Task->connection = 'test'; - $this->Task->path = '/my/path/'; - - $result = $this->Task->bake('Article', false, array( - 'fromTable' => true, 'schema' => 'Article', 'records' => false - )); - - $this->assertStringContainsString('class ArticleFixture extends CakeTestFixture', $result); - $this->assertStringContainsString('public $records', $result); - $this->assertStringContainsString('public $import', $result); - $this->assertStringContainsString("'title' => 'First Article'", $result, 'Missing import data'); - $this->assertStringContainsString('Second Article', $result, 'Missing import data'); - } - -/** - * 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->assertStringContainsString("'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->assertStringContainsString("'body' => 'Body \"value\"'", $result, 'Data has bad escaping'); - } - -/** - * test that execute includes import options - * - * @return void - */ - public function testExecuteWithImportSchema() { - $this->Task->connection = 'test'; - $this->Task->path = '/my/path/'; - $this->Task->args = array('article'); - $this->Task->params = array( - 'schema' => true, - 'records' => false, - ); - $filename = '/my/path/ArticleFixture.php'; - - $this->Task->expects($this->never()) - ->method('in'); - - $this->Task->expects($this->at(0)) - ->method('createFile') - ->with($filename, $this->logicalAnd( - $this->stringContains('class ArticleFixture'), - $this->stringContains("\$import = array('model' => 'Article'") - )); - - $this->Task->execute(); - } - -/** - * test that execute includes import options - * - * @return void - */ - public function testExecuteWithImportRecords() { - $this->Task->connection = 'test'; - $this->Task->path = '/my/path/'; - $this->Task->args = array('article'); - $this->Task->params = array( - 'schema' => true, - 'records' => true, - ); - $filename = '/my/path/ArticleFixture.php'; - - $this->Task->expects($this->never()) - ->method('in'); - - $this->Task->expects($this->at(0)) - ->method('createFile') - ->with($filename, $this->logicalAnd( - $this->stringContains('class ArticleFixture'), - $this->stringContains("\$import = array('model' => 'Article', 'connection' => 'test')") - )); - - $this->Task->execute(); - } - -/** - * 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 using all() with -schema - * - * @return void - */ - public function testAllWithSchemaImport() { - $this->Task->connection = 'test'; - $this->Task->path = '/my/path/'; - $this->Task->args = array('all'); - $this->Task->params = array('schema' => 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('public $import = array(\'model\' => \'Article\'')); - - $filename = '/my/path/CommentFixture.php'; - $this->Task->expects($this->at(1))->method('createFile') - ->with($filename, $this->stringContains('public $import = array(\'model\' => \'Comment\'')); - $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->assertStringContainsString('class ArticleFixture extends CakeTestFixture', $result); - $this->assertStringContainsString('public $fields', $result); - $this->assertStringContainsString('public $records', $result); - $this->assertStringNotContainsString('public $import', $result); - - $result = $this->Task->bake('Article', 'comments'); - $this->assertStringContainsString('class ArticleFixture extends CakeTestFixture', $result); - $this->assertStringContainsString('public $table = \'comments\';', $result); - $this->assertStringContainsString('public $fields = array(', $result); - - $result = $this->Task->bake('Article', 'comments', array('records' => true)); - $this->assertStringContainsString("public \$import = array('records' => true, 'connection' => 'test');", $result); - $this->assertStringNotContainsString('public $records', $result); - - $result = $this->Task->bake('Article', 'comments', array('schema' => 'Article')); - $this->assertStringContainsString("public \$import = array('model' => 'Article', 'connection' => 'test');", $result); - $this->assertStringNotContainsString('public $fields', $result); - - $result = $this->Task->bake('Article', 'comments', array('schema' => 'Article', 'records' => true)); - $this->assertStringContainsString("public \$import = array('model' => 'Article', 'records' => true, 'connection' => 'test');", $result); - $this->assertStringNotContainsString('public $fields', $result); - $this->assertStringNotContainsString('public $records', $result); - } - -/** - * test record generation with various integer, float and binary types - * - * @return void - */ - public function testRecordGenerationForBinaryFloatAndIntegerTypes() { - $this->Task->connection = 'test'; - $this->Task->path = '/my/path/'; - - $result = $this->Task->bake('Article', 'datatypes'); - $this->assertStringContainsString("'float_field' => 1", $result); - $this->assertStringContainsString("'bool' => 1", $result); - $this->assertStringContainsString("'tiny_int' => 1", $result); - $this->assertStringContainsString("'small_int' => 1", $result); - $this->assertStringContainsString("'huge_int' => 1", $result); - - $result = $this->Task->bake('Article', 'binary_tests'); - $this->assertStringContainsString("'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('Task->generateFixtureFile('Article', array()); - $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')); - - $this->Task->generateFixtureFile('Article', array()); - CakePlugin::unload(); - } - -} diff --git a/lib/Cake/Test/Case/Console/Command/Task/ModelTaskTest.php b/lib/Cake/Test/Case/Console/Command/Task/ModelTaskTest.php deleted file mode 100644 index 2df4980d05..0000000000 --- a/lib/Cake/Test/Case/Console/Command/Task/ModelTaskTest.php +++ /dev/null @@ -1,1327 +0,0 @@ -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() : void { - 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'); - - $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 getting 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('notBlank', $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('notBlank' => 'notBlank'); - $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('26', 'y', '18', 'n')); - - $result = $this->Task->fieldValidation('text', array('type' => 'string', 'length' => 10, 'null' => false)); - $expected = array('notBlank' => 'notBlank', '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', '26', '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('notBlank' => 'notBlank'); - $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 that skipping fields during rule choice works when doing interactive field validation. - * - * @return void - */ - public function testSkippingChoiceInteractiveFieldValidation() { - $this->Task->initValidations(); - $this->Task->interactive = true; - $this->Task->expects($this->any())->method('in') - ->will($this->onConsecutiveCalls('26', 'y', 's')); - - $result = $this->Task->fieldValidation('text', array('type' => 'string', 'length' => 10, 'null' => false)); - $expected = array('notBlank' => 'notBlank', '_skipFields' => true); - $this->assertEquals($expected, $result); - } - -/** - * Test that skipping fields after rule choice works when doing interactive field validation. - * - * @return void - */ - public function testSkippingAnotherInteractiveFieldValidation() { - $this->Task->initValidations(); - $this->Task->interactive = true; - $this->Task->expects($this->any())->method('in') - ->will($this->onConsecutiveCalls('26', 's')); - - $result = $this->Task->fieldValidation('text', array('type' => 'string', 'length' => 10, 'null' => false)); - $expected = array('notBlank' => 'notBlank', '_skipFields' => true); - $this->assertEquals($expected, $result); - } - -/** - * Test the validation generation routine with skipping the rest of the fields - * when doing interactive field validation. - * - * @return void - */ - public function testInteractiveDoValidationWithSkipping() { - $this->Task->expects($this->any()) - ->method('in') - ->will($this->onConsecutiveCalls('37', '26', 'n', '10', 's')); - $this->Task->interactive = true; - $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, - ) - ) - )); - - $result = $this->Task->doValidation($Model); - $expected = array( - 'name' => array( - 'notBlank' => 'notBlank' - ), - 'email' => array( - 'email' => 'email', - ), - ); - $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( - 'notBlank' => 'notBlank' - ), - '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); - } - -/** - * test non interactive doActsAs - * - * @return void - */ - public function testDoActsAs() { - $this->Task->connection = 'test'; - $this->Task->interactive = false; - $model = new Model(array('ds' => 'test', 'name' => 'NumberTree')); - $result = $this->Task->doActsAs($model); - - $this->assertEquals(array('Tree'), $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( - 'notBlank' => 'notBlank' - ), - 'email' => array( - 'email' => 'email', - ), - 'some_date' => array( - 'date' => 'date' - ), - 'some_time' => array( - 'time' => 'time' - ) - ); - $result = $this->Task->bake('BakeArticle', compact('validate')); - $this->assertMatchesRegularExpression('/class BakeArticle extends AppModel \{/', $result); - $this->assertMatchesRegularExpression('/\$validate \= array\(/', $result); - $expected = <<< STRINGEND -array( - 'notBlank' => array( - 'rule' => array('notBlank'), - //'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->assertMatchesRegularExpression('/' . 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->assertStringContainsString(' * @property BakeUser $BakeUser', $result); - $this->assertStringContainsString(' * @property OtherModel $OtherModel', $result); - $this->assertStringContainsString(' * @property BakeComment $BakeComment', $result); - $this->assertStringContainsString(' * @property BakeTag $BakeTag', $result); - $this->assertMatchesRegularExpression('/\$hasAndBelongsToMany \= array\(/', $result); - $this->assertMatchesRegularExpression('/\$hasMany \= array\(/', $result); - $this->assertMatchesRegularExpression('/\$belongsTo \= array\(/', $result); - $this->assertMatchesRegularExpression('/\$hasOne \= array\(/', $result); - $this->assertMatchesRegularExpression('/BakeTag/', $result); - $this->assertMatchesRegularExpression('/OtherModel/', $result); - $this->assertMatchesRegularExpression('/SomethingElse/', $result); - $this->assertMatchesRegularExpression('/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->assertStringContainsString("App::uses('ControllerTestAppModel', 'ControllerTest.Model');", $result); - - $this->assertEquals(count(ClassRegistry::keys()), 0); - $this->assertEquals(count(ClassRegistry::mapKeys()), 0); - } - -/** - * test bake() for models with behaviors - * - * @return void - */ - public function testBakeWithBehaviors() { - $result = $this->Task->bake('NumberTree', array('actsAs' => array('Tree', 'PluginName.Sluggable'))); - $expected = <<assertTextContains($expected, $result); - } - -/** - * 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(6))->method('bake'); - $this->Task->Test->expects($this->exactly(6))->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')); - - $filename = '/my/path/NumberTree.php'; - $this->Task->expects($this->at(6))->method('createFile') - ->with($filename, $this->stringContains('class NumberTree')); - - $this->Task->execute(); - - $this->assertEquals(count(ClassRegistry::keys()), 0); - $this->assertEquals(count(ClassRegistry::mapKeys()), 0); - } - -/** - * test that odd tablenames aren't 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', 'doActsAs', '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())); - $this->Task->expects($this->once())->method('doActsAs')->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 aren't 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', 'doActsAs', '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())); - $this->Task->expects($this->once())->method('doActsAs')->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', 'number_trees'); - - $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/lib/Cake/Test/Case/Console/Command/Task/PluginTaskTest.php b/lib/Cake/Test/Case/Console/Command/Task/PluginTaskTest.php deleted file mode 100644 index c5e879d180..0000000000 --- a/lib/Cake/Test/Case/Console/Command/Task/PluginTaskTest.php +++ /dev/null @@ -1,221 +0,0 @@ -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) - 1; - App::build(array('plugins' => $paths)); - } - -/** - * tearDown() - * - * @return void - */ - public function tearDown() : void { - 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', - 'Console' . DS . 'Command' . DS . 'Task', - 'Console' . DS . 'Templates', - 'Controller' . DS . 'Component', - 'Lib', - 'Locale' . DS . 'eng' . DS . 'LC_MESSAGES', - 'Model' . DS . 'Behavior', - 'Model' . DS . 'Datasource', - 'Test' . DS . 'Case' . DS . 'Controller' . DS . 'Component', - 'Test' . DS . 'Case' . DS . 'Lib', - 'Test' . DS . 'Case' . DS . 'Model' . DS . 'Behavior', - 'Test' . DS . 'Case' . DS . 'Model' . DS . 'Datasource', - 'Test' . DS . 'Case' . DS . 'View' . DS . 'Helper', - 'Test' . DS . 'Fixture', - 'View' . DS . 'Elements', - 'View' . DS . 'Helper', - 'View' . DS . 'Layouts', - 'webroot' . DS . 'css', - 'webroot' . DS . 'js', - 'webroot' . DS . 'img', - ); - 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, $this->anything()); - - $file = $path . DS . 'Model' . DS . 'TestPluginAppModel.php'; - $this->Task->expects($this->at(4))->method('createFile') - ->with($file, $this->anything()); - - $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); - - array_unshift($paths, '/fake/path'); - $paths[] = '/fake/path2'; - - $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/lib/Cake/Test/Case/Console/Command/Task/ProjectTaskTest.php b/lib/Cake/Test/Case/Console/Command/Task/ProjectTaskTest.php deleted file mode 100644 index 72c5563c1b..0000000000 --- a/lib/Cake/Test/Case/Console/Command/Task/ProjectTaskTest.php +++ /dev/null @@ -1,385 +0,0 @@ -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() : void { - 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->assertMatchesRegularExpression('/define\(\'CAKE_CORE_INCLUDE_PATH\', .*?DS/', $contents); - $File = new File($path . DS . 'webroot' . DS . 'test.php'); - $contents = $File->read(); - $this->assertMatchesRegularExpression('/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->assertMatchesRegularExpression('#//define\(\'CAKE_CORE_INCLUDE_PATH#', $contents); - - $contents = file_get_contents($path . DS . 'webroot' . DS . 'test.php'); - $this->assertMatchesRegularExpression('#//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 . '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->assertDoesNotMatchRegularExpression('/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->assertDoesNotMatchRegularExpression('/76859309657453542496749683645/', $contents, 'Default CipherSeed left behind. %s'); - } - -/** - * test generation of cache prefix - * - * @return void - */ - public function testCachePrefixGeneration() { - $this->_setupTestProject(); - - $path = $this->Task->path . 'bake_test_app' . DS; - $result = $this->Task->cachePrefix($path); - $this->assertTrue($result); - - $File = new File($path . 'Config' . DS . 'core.php'); - $contents = $File->read(); - $this->assertMatchesRegularExpression('/\$prefix = \'.+\';/', $contents, '$prefix is not defined'); - $this->assertDoesNotMatchRegularExpression('/\$prefix = \'myapp_\';/', $contents, 'Default cache prefix 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->assertDoesNotMatchRegularExpression('/define\(\'CAKE_CORE_INCLUDE_PATH\', ROOT/', $contents); - $File = new File($path . 'webroot' . DS . 'test.php'); - $contents = $File->read(); - $this->assertDoesNotMatchRegularExpression('/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(CONFIG . '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->assertDoesNotMatchRegularExpression('/__CAKE_PATH__/', $contents, 'Console path placeholder left behind.'); - } -} diff --git a/lib/Cake/Test/Case/Console/Command/Task/TemplateTaskTest.php b/lib/Cake/Test/Case/Console/Command/Task/TemplateTaskTest.php deleted file mode 100644 index e90968f060..0000000000 --- a/lib/Cake/Test/Case/Console/Command/Task/TemplateTaskTest.php +++ /dev/null @@ -1,164 +0,0 @@ -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() : void { - 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->assertMatchesRegularExpression('/ArticleFixture extends CakeTestFixture/', $result); - } -} diff --git a/lib/Cake/Test/Case/Console/Command/Task/TestTaskTest.php b/lib/Cake/Test/Case/Console/Command/Task/TestTaskTest.php deleted file mode 100644 index e53693da1c..0000000000 --- a/lib/Cake/Test/Case/Console/Command/Task/TestTaskTest.php +++ /dev/null @@ -1,755 +0,0 @@ - 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 - */ -class TestTaskTag extends Model { - -/** - * 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 - */ -class TestTaskAppModel extends Model { -} - -/** - * Testing AppMode (TaskComment) - * - * @package Cake.Test.Case.Console.Command.Task - */ -class TestTaskComment extends TestTaskAppModel { - -/** - * 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 - */ -class TestTaskCommentsController extends Controller { - -/** - * 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() : void { - 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() : void { - 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)); - $this->Task->buildTestSubject('Model', 'TestTaskComment'); - - $keys = ClassRegistry::keys(); - $this->assertFalse(in_array('random', $keys)); - } - -/** - * test that getClassName returns the user choice as a class name. - * - * @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 class names 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 class names 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->assertStringContainsString("App::uses('TestTaskArticle', 'Model')", $result); - $this->assertStringContainsString('class TestTaskArticleTest extends CakeTestCase', $result); - - $this->assertStringContainsString('function setUp()', $result); - $this->assertStringContainsString("\$this->TestTaskArticle = ClassRegistry::init('TestTaskArticle')", $result); - - $this->assertStringContainsString('function tearDown()', $result); - $this->assertStringContainsString('unset($this->TestTaskArticle)', $result); - - $this->assertStringContainsString('function testDoSomething()', $result); - $this->assertStringContainsString('function testDoSomethingElse()', $result); - $this->assertStringContainsString('$this->markTestIncomplete(\'testDoSomething not implemented.\')', $result); - $this->assertStringContainsString('$this->markTestIncomplete(\'testDoSomethingElse not implemented.\')', $result); - - $this->assertStringContainsString("'app.test_task_article'", $result); - $this->assertStringContainsString("'app.test_task_comment'", $result); - $this->assertStringContainsString("'app.test_task_tag'", $result); - $this->assertStringContainsString("'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->assertStringContainsString("App::uses('TestTaskCommentsController', 'Controller')", $result); - $this->assertStringContainsString('class TestTaskCommentsControllerTest extends ControllerTestCase', $result); - - $this->assertStringNotContainsString('function setUp()', $result); - $this->assertStringNotContainsString("\$this->TestTaskComments = new TestTaskCommentsController()", $result); - $this->assertStringNotContainsString("\$this->TestTaskComments->constructClasses()", $result); - - $this->assertStringNotContainsString('function tearDown()', $result); - $this->assertStringNotContainsString('unset($this->TestTaskComments)', $result); - - $this->assertStringContainsString("'app.test_task_article'", $result); - $this->assertStringContainsString("'app.test_task_comment'", $result); - $this->assertStringContainsString("'app.test_task_tag'", $result); - $this->assertStringContainsString("'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->assertStringContainsString("App::uses('Component', 'Controller')", $result); - $this->assertStringContainsString("App::uses('ComponentCollection', 'Controller')", $result); - $this->assertStringContainsString("App::uses('ExampleComponent', 'Controller/Component')", $result); - $this->assertStringContainsString('class ExampleComponentTest extends CakeTestCase', $result); - - $this->assertStringContainsString('function setUp()', $result); - $this->assertStringContainsString("\$Collection = new ComponentCollection()", $result); - $this->assertStringContainsString("\$this->Example = new ExampleComponent(\$Collection)", $result); - - $this->assertStringContainsString('function tearDown()', $result); - $this->assertStringContainsString('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->assertStringContainsString("App::uses('ExampleBehavior', 'Model/Behavior')", $result); - $this->assertStringContainsString('class ExampleBehaviorTest extends CakeTestCase', $result); - - $this->assertStringContainsString('function setUp()', $result); - $this->assertStringContainsString("\$this->Example = new ExampleBehavior()", $result); - - $this->assertStringContainsString('function tearDown()', $result); - $this->assertStringContainsString('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->assertStringContainsString("App::uses('ExampleHelper', 'View/Helper')", $result); - $this->assertStringContainsString('class ExampleHelperTest extends CakeTestCase', $result); - - $this->assertStringContainsString('function setUp()', $result); - $this->assertStringContainsString("\$View = new View()", $result); - $this->assertStringContainsString("\$this->Example = new ExampleHelper(\$View)", $result); - - $this->assertStringContainsString('function tearDown()', $result); - $this->assertStringContainsString('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() - * - * @return void - */ - 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/lib/Cake/Test/Case/Console/Command/Task/ViewTaskTest.php b/lib/Cake/Test/Case/Console/Command/Task/ViewTaskTest.php deleted file mode 100644 index 639e849212..0000000000 --- a/lib/Cake/Test/Case/Console/Command/Task/ViewTaskTest.php +++ /dev/null @@ -1,700 +0,0 @@ - array( - 'className' => 'TestTest.ViewTaskArticle', - 'foreignKey' => 'article_id' - ) - ); -} - -/** - * Test View Task Article Model - * - * @package Cake.Test.Case.Console.Command.Task - */ -class ViewTaskArticle extends Model { - -/** - * Table name - * - * @var string - */ - public $useTable = 'articles'; -} - -/** - * Test View Task Comments Controller - * - * @package Cake.Test.Case.Console.Command.Task - */ -class ViewTaskCommentsController extends Controller { - -/** - * 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 - */ -class ViewTaskArticlesController extends Controller { - -/** - * 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() : void { - 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() : void { - 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->assertMatchesRegularExpression('/Delete Test View Model/', $result); - $this->assertMatchesRegularExpression('/Edit Test View Model/', $result); - $this->assertMatchesRegularExpression('/List Test View Models/', $result); - $this->assertMatchesRegularExpression('/New Test View Model/', $result); - - $this->assertMatchesRegularExpression('/testViewModel\[\'TestViewModel\'\]\[\'id\'\]/', $result); - $this->assertMatchesRegularExpression('/testViewModel\[\'TestViewModel\'\]\[\'name\'\]/', $result); - $this->assertMatchesRegularExpression('/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->assertMatchesRegularExpression('/Delete Test View Model/', $result); - $this->assertMatchesRegularExpression('/Edit Test View Model/', $result); - $this->assertMatchesRegularExpression('/List Test View Models/', $result); - $this->assertMatchesRegularExpression('/New Test View Model/', $result); - - $this->assertMatchesRegularExpression('/testViewModel\[\'TestViewModel\'\]\[\'id\'\]/', $result); - $this->assertMatchesRegularExpression('/testViewModel\[\'TestViewModel\'\]\[\'name\'\]/', $result); - $this->assertMatchesRegularExpression('/testViewModel\[\'TestViewModel\'\]\[\'body\'\]/', $result); - - $result = $this->Task->getContent('admin_add', $vars); - $this->assertMatchesRegularExpression("/input\('name'\)/", $result); - $this->assertMatchesRegularExpression("/input\('body'\)/", $result); - $this->assertMatchesRegularExpression('/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'; - - $expected = file_get_contents(CAKE . 'Test' . DS . 'bake_compare' . DS . 'View' . DS . 'index.ctp'); - $this->Task->expects($this->at(0))->method('createFile') - ->with( - TMP . 'ViewTaskComments' . DS . 'index.ctp', - $expected - ); - $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->assertStringNotContainsString('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/lib/Cake/Test/Case/Console/ShellDispatcherTest.php b/lib/Cake/Test/Case/Console/ShellDispatcherTest.php index eb5edd0da1..498a2e8c72 100644 --- a/lib/Cake/Test/Case/Console/ShellDispatcherTest.php +++ b/lib/Cake/Test/Case/Console/ShellDispatcherTest.php @@ -280,7 +280,7 @@ public function testParseParams() { '-dry', '-f', '-name', - 'DbAcl' + 'XXX' ); $expected = array( 'app' => 'app', @@ -293,7 +293,7 @@ public function testParseParams() { $this->assertEquals($expected, $Dispatcher->params); $expected = array( - './console/cake.php', 'schema', 'run', 'create', '-dry', '-f', '-name', 'DbAcl' + './console/cake.php', 'schema', 'run', 'create', '-dry', '-f', '-name', 'XXX' ); $this->assertEquals($expected, $Dispatcher->args); @@ -306,7 +306,7 @@ public function testParseParams() { 'create', '-dry', '-name', - 'DbAcl' + 'XXX' ); $expected = array( 'app' => 'app', diff --git a/lib/Cake/Test/Case/Controller/ApplicationControllerTest.php b/lib/Cake/Test/Case/Controller/ApplicationControllerTest.php index 6c658b6d08..491361460d 100644 --- a/lib/Cake/Test/Case/Controller/ApplicationControllerTest.php +++ b/lib/Cake/Test/Case/Controller/ApplicationControllerTest.php @@ -1,5 +1,7 @@ array('with' => 'PermissionTwoTest')); -} - -/** - * AcoTwoTest class - * - * @package Cake.Test.Case.Controller.Component.Acl - */ -class AcoTwoTest extends AclNodeTwoTestBase { - -/** - * name property - * - * @var string - */ - public $name = 'AcoTwoTest'; - -/** - * useTable property - * - * @var string - */ - 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 - */ - public $name = 'PermissionTwoTest'; - -/** - * useTable property - * - * @var string - */ - public $useTable = 'aros_aco_twos'; - -/** - * cacheQueries property - * - * @var bool - */ - public $cacheQueries = false; - -/** - * belongsTo property - * - * @var array - */ - public $belongsTo = array('AroTwoTest' => array('foreignKey' => 'aro_id'), 'AcoTwoTest' => array('foreignKey' => 'aco_id')); - -/** - * actsAs property - * - * @var mixed - */ - public $actsAs = null; -} - -/** - * DbAclTwoTest class - * - * @package Cake.Test.Case.Controller.Component.Acl - */ -class DbAclTwoTest extends DbAcl { - -/** - * construct method - */ - 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() : void { - 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() : void { - 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 - * - * @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')); - } - -/** - * Test that allow() with an invalid permission name triggers an error. - * - * @return void - */ - public function testAllowInvalidPermission() { - $this->expectException(CakeException::class); - $this->assertFalse($this->Acl->allow('Micheal', 'tpsReports', 'derp')); - } - -/** - * testAllowInvalidNode method - * - * @return void - */ - public function testAllowInvalidNode() { - $this->assertFalse($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 - * - * @return void - */ - public function testCheckInvalidNode() { - $this->assertFalse($this->Acl->check('WRONG', 'tpsReports', 'read')); - } - -/** - * testCheckInvalidPermission method - * - * @return void - */ - public function testCheckInvalidPermission() { - $this->assertFalse($this->Acl->check('Lumbergh', 'smash', 'foobar')); - } - -/** - * testCheckMissingPermission method - * - * @return void - */ - public function testCheckMissingPermission() { - $this->assertFalse($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 - * - * @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')); - } - -/** - * test inherit from deny method - * - * @return void - */ - public function testInheritParentDeny() { - $this->Acl->Aco->create(array('parent_id' => null, 'alias' => 'world')); - $this->Acl->Aco->save(); - - $this->Acl->Aco->create(array('parent_id' => $this->Acl->Aco->id, 'alias' => 'town')); - $this->Acl->Aco->save(); - - $this->Acl->Aco->create(array('parent_id' => null, 'alias' => 'bizzaro_world')); - $this->Acl->Aco->save(); - - $this->Acl->Aco->create(array('parent_id' => $this->Acl->Aco->id, 'alias' => 'bizzaro_town')); - $this->Acl->Aco->save(); - - $this->Acl->Aro->create(array('parent_id' => null, 'alias' => 'Jane')); - $this->Acl->Aro->save(); - - // Setup deny on create for parent - $this->Acl->allow('Jane', 'world', '*'); - $this->Acl->deny('Jane', 'world', 'create'); - - // Setup inherit and specify allow for create on child. - $this->Acl->inherit('Jane', 'town', '*'); - $this->Acl->allow('Jane', 'town', 'create'); - - // Setup deny on create for parent - $this->Acl->deny('Jane', 'bizzaro_world', '*'); - $this->Acl->allow('Jane', 'bizzaro_world', 'create'); - - // Setup inherit. - $this->Acl->inherit('Jane', 'bizzaro_town', '*'); - - $this->assertTrue($this->Acl->check('Jane', 'town', 'create'), 'Should have access due to override'); - $this->assertTrue($this->Acl->check('Jane', 'town', '*'), 'Should have access due to inherit'); - - $this->assertTrue($this->Acl->check('Jane', 'bizzaro_town', 'create'), 'Should have access due explicit allow'); - $this->assertFalse($this->Acl->check('Jane', 'bizzaro_town', '*'), 'Should not have access due to inherit'); - } - -/** - * testDbGrant method - * - * @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 - * - * @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); - } - $permissions = 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 int $len - * @return void - */ - protected function _pad($string = '', $len = 14) { - return str_pad($string, $len); - } -} diff --git a/lib/Cake/Test/Case/Controller/Component/Acl/IniAclTest.php b/lib/Cake/Test/Case/Controller/Component/Acl/IniAclTest.php deleted file mode 100644 index 0301b678ab..0000000000 --- a/lib/Cake/Test/Case/Controller/Component/Acl/IniAclTest.php +++ /dev/null @@ -1,68 +0,0 @@ -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/lib/Cake/Test/Case/Controller/Component/Acl/PhpAclTest.php b/lib/Cake/Test/Case/Controller/Component/Acl/PhpAclTest.php deleted file mode 100644 index 07bfdc0370..0000000000 --- a/lib/Cake/Test/Case/Controller/Component/Acl/PhpAclTest.php +++ /dev/null @@ -1,371 +0,0 @@ -PhpAcl = new PhpAcl(); - $this->Acl = new AclComponent($Collection, array( - 'adapter' => array( - 'config' => CAKE . 'Test' . DS . 'test_app' . DS . 'Config' . DS . 'acl.php', - ), - )); - } - -/** - * Test role inheritance - * - * @return void - */ - 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]); - } - -/** - * Test adding a role - * - * @return void - */ - 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')); - } - -/** - * Test resolving ARO - * - * @return void - */ - public function testAroResolve() { - $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 - * - * @return void - */ - 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 - * - * @return void - */ - 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 - * - * @return void - */ - 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 - * - * @return void - */ - 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 - * - * @return void - */ - 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 - * - * @return void - */ - public function testInvalidConfigWithAroMissing() { - $this->expectException('AclException'); - $this->expectExceptionMessage('"roles" section not found in configuration'); - $config = array('aco' => array('allow' => array('foo' => ''))); - $this->PhpAcl->build($config); - } - - public function testInvalidConfigWithAcosMissing() { - $this->expectException('AclException'); - $this->expectExceptionMessage('Neither "allow" nor "deny" rules were provided in configuration.'); - - $config = array( - 'roles' => array('Role/foo' => null), - ); - - $this->PhpAcl->build($config); - } - -/** - * test resolving of ACOs - * - * @return void - */ - 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 - * - * @return void - */ - 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(); - $this->expectErrorMessage('cycle detected'); - $this->PhpAcl->build($config); - } - -/** - * test that with policy allow, only denies count - * - * @return void - */ - 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/lib/Cake/Test/Case/Controller/Component/AclComponentTest.php b/lib/Cake/Test/Case/Controller/Component/AclComponentTest.php deleted file mode 100644 index b0e226b2bd..0000000000 --- a/lib/Cake/Test/Case/Controller/Component/AclComponentTest.php +++ /dev/null @@ -1,91 +0,0 @@ - - * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) - * - * Licensed under The MIT License - * For full copyright and license information, please see the LICENSE.txt - * Redistributions of files must retain the above copyright notice - * - * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) - * @link https://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 https://opensource.org/licenses/mit-license.php MIT License - */ - -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(): void { - 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(): void { - parent::tearDown(); - unset($this->Acl); - } - -/** - * test that constructor throws an exception when Acl.classname is a - * non-existent class - * - * @return void - */ - public function testConstrutorException() { - $this->expectException(CakeException::class); - Configure::write('Acl.classname', 'AclClassNameThatDoesNotExist'); - $Collection = new ComponentCollection(); - new AclComponent($Collection); - } - -/** - * test that adapter() allows control of the internal implementation AclComponent uses. - * - * @return void - */ - public function testAdapter() { - $Adapter = $this->getMock('AclInterface'); - $Adapter->expects($this->once())->method('initialize')->with($this->Acl); - - $this->assertNull($this->Acl->adapter($Adapter)); - $this->assertEquals($this->Acl->adapter(), $Adapter, 'Returned object is different %s'); - } - -/** - * test that adapter() whines when the class does not implement AclInterface - * - * @return void - */ - public function testAdapterException() { - $this->expectException(CakeException::class); - $thing = new StdClass(); - $this->Acl->adapter($thing); - } - -} diff --git a/lib/Cake/Test/Case/Controller/Component/Auth/ActionsAuthorizeTest.php b/lib/Cake/Test/Case/Controller/Component/Auth/ActionsAuthorizeTest.php deleted file mode 100644 index 6658213cc6..0000000000 --- a/lib/Cake/Test/Case/Controller/Component/Auth/ActionsAuthorizeTest.php +++ /dev/null @@ -1,197 +0,0 @@ -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 = 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); - } - -/** - * 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/lib/Cake/Test/Case/Controller/Component/Auth/CrudAuthorizeTest.php b/lib/Cake/Test/Case/Controller/Component/Auth/CrudAuthorizeTest.php deleted file mode 100644 index 784909e592..0000000000 --- a/lib/Cake/Test/Case/Controller/Component/Auth/CrudAuthorizeTest.php +++ /dev/null @@ -1,189 +0,0 @@ -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. - * - * @return void - */ - public function testAuthorizeNoMappedAction() { - $this->expectWarning(); - $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', - '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/lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php b/lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php index 2d6af32cd2..f2c30b7d4c 100644 --- a/lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php +++ b/lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php @@ -18,7 +18,6 @@ App::uses('Controller', 'Controller'); App::uses('AuthComponent', 'Controller/Component'); -App::uses('AclComponent', 'Controller/Component'); App::uses('BaseAuthenticate', 'Controller/Component/Auth'); App::uses('FormAuthenticate', 'Controller/Component/Auth'); App::uses('CakeEvent', 'Event'); diff --git a/lib/Cake/Test/Case/Core/AppTest.php b/lib/Cake/Test/Case/Core/AppTest.php index aaed37b6f7..cbfb028d11 100644 --- a/lib/Cake/Test/Case/Core/AppTest.php +++ b/lib/Cake/Test/Case/Core/AppTest.php @@ -334,9 +334,9 @@ public function testListObjects() { $this->assertTrue(in_array('HtmlHelper', $result)); $result = App::objects('model', null, false); - $this->assertTrue(in_array('AcoAction', $result)); + $this->assertTrue(in_array('Model', $result)); $result = App::objects('Model', null, false); - $this->assertTrue(in_array('AcoAction', $result)); + $this->assertTrue(in_array('Model', $result)); $result = App::objects('file'); $this->assertFalse($result); diff --git a/lib/Cake/Test/Case/Core/ConfigureTest.php b/lib/Cake/Test/Case/Core/ConfigureTest.php index 356268107a..3bc49c59ba 100644 --- a/lib/Cake/Test/Case/Core/ConfigureTest.php +++ b/lib/Cake/Test/Case/Core/ConfigureTest.php @@ -334,8 +334,8 @@ public function testLoadWithMerge() { $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')); + $this->assertEquals('Overwrite', Configure::read('TestXXX.classname')); + $this->assertEquals('one', Configure::read('TestXXX.custom')); } /** diff --git a/lib/Cake/Test/Case/Model/AclNodeTest.php b/lib/Cake/Test/Case/Model/AclNodeTest.php deleted file mode 100644 index 555c70bb93..0000000000 --- a/lib/Cake/Test/Case/Model/AclNodeTest.php +++ /dev/null @@ -1,355 +0,0 @@ - - * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) - * - * Licensed under The MIT License - * For full copyright and license information, please see the LICENSE.txt - * Redistributions of files must retain the above copyright notice - * - * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) - * @link https://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 https://opensource.org/licenses/mit-license.php MIT License - */ - -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 - */ - public $useDbConfig = 'test'; - -/** - * cacheSources property - * - * @var bool - */ - public $cacheSources = false; -} - -/** - * Aro Test Wrapper - * - * @package Cake.Test.Case.Model - */ -class DbAroTest extends DbAclNodeTestBase { - -/** - * useTable property - * - * @var string - */ - 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 { - -/** - * useTable property - * - * @var string - */ - 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 { - -/** - * useTable property - * - * @var string - */ - public $useTable = 'aros_acos'; - -/** - * cacheQueries property - * - * @var bool - */ - 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 { - -/** - * useTable property - * - * @var string - */ - 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 - */ - public $name = 'AuthUser'; - -/** - * useTable property - * - * @var string - */ - 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 { - -/** - * Constructor - */ - 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(): void { - 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/lib/Cake/Test/Case/Model/Behavior/AclBehaviorTest.php b/lib/Cake/Test/Case/Model/Behavior/AclBehaviorTest.php deleted file mode 100644 index e0f4d449df..0000000000 --- a/lib/Cake/Test/Case/Model/Behavior/AclBehaviorTest.php +++ /dev/null @@ -1,484 +0,0 @@ - '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; - } - 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 - * - * @return null - */ - 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 - * - * @return null - */ - 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(): void { - parent::setUp(); - Configure::write('Acl.database', 'test'); - - $this->Aco = new Aco(); - $this->Aro = new Aro(); - } - -/** - * tearDown method - * - * @return void - */ - public function tearDown(): void { - parent::tearDown(); - unset($this->Aro, $this->Aco); - } - -/** - * Test Setup of AclBehavior - * - * @return void - */ - public function testsetUp() { - parent::setUp(); - $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/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php b/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php index 21f6d2a15b..d927d51f61 100644 --- a/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php @@ -2094,8 +2094,8 @@ public function testStringConditionsParsing() { $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"; + $result = $this->Dbo->conditions("Xxx.rght = Xxx.lft + 1.1"); + $expected = " WHERE `Xxx`.`rght` = `Xxx`.`lft` + 1.1"; $this->assertEquals($expected, $result); $date = date('Y-m-d H:i:s'); diff --git a/lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php b/lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php index 5cb05c46d2..64e3456c21 100644 --- a/lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php @@ -1416,10 +1416,10 @@ public function testTransactionNested() { $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(1))->method('exec')->with($this->equalTo('SAVEPOINT LEVEL1'))->will($this->returnValue(0)); + $conn->expects($this->at(2))->method('exec')->with($this->equalTo('RELEASE SAVEPOINT LEVEL1'))->will($this->returnValue(0)); + $conn->expects($this->at(3))->method('exec')->with($this->equalTo('SAVEPOINT LEVEL1'))->will($this->returnValue(0)); + $conn->expects($this->at(4))->method('exec')->with($this->equalTo('ROLLBACK TO SAVEPOINT LEVEL1'))->will($this->returnValue(0)); $conn->expects($this->at(5))->method('commit')->will($this->returnValue(true)); $this->_runTransactions($db); diff --git a/lib/Cake/Test/Case/Utility/ClassRegistryTest.php b/lib/Cake/Test/Case/Utility/ClassRegistryTest.php index e2ca332970..a7e3edc323 100644 --- a/lib/Cake/Test/Case/Utility/ClassRegistryTest.php +++ b/lib/Cake/Test/Case/Utility/ClassRegistryTest.php @@ -200,15 +200,15 @@ public function testAddModelWithAlias() { } /** - * Test that init() can make the Aco models with alias set properly + * Test that init() can make the SomeModel models with alias set properly * * @return void */ - public function testAddModelWithAliasAco() { - $aco = ClassRegistry::init(array('class' => 'Aco', 'alias' => 'CustomAco')); - $this->assertInstanceOf('Aco', $aco); - $this->assertSame('Aco', $aco->name); - $this->assertSame('CustomAco', $aco->alias); + public function testAddModelWithAliasModel() { + $mod = ClassRegistry::init(array('class' => 'Model', 'alias' => 'CustomModel')); + $this->assertInstanceOf('Model', $mod); + $this->assertSame('Model', $mod->name); + $this->assertSame('CustomModel', $mod->alias); } /** diff --git a/lib/Cake/Test/Case/Utility/DebuggerTest.php b/lib/Cake/Test/Case/Utility/DebuggerTest.php index b896028d10..f50658ffcd 100644 --- a/lib/Cake/Test/Case/Utility/DebuggerTest.php +++ b/lib/Cake/Test/Case/Utility/DebuggerTest.php @@ -643,7 +643,10 @@ public function testNoDbCredentials() { */ public function testExportVarRecursion() { $output = Debugger::exportVar($GLOBALS); - $this->assertStringContainsString("'GLOBALS' => [recursion]", $output); + if (strpos($output, 'GLOBALS') === false) { + $this->markTestSkipped('restriced GLOBALS access in php >= 8.1'); + } + $this->assertStringContainsString("'GLOBALS' => [recursion]", $output); } /** diff --git a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php index 046919ebcf..26f2b9e599 100644 --- a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php @@ -1712,6 +1712,12 @@ public function testSecuredFileInput() { 'Attachment.file.name', 'Attachment.file.type', 'Attachment.file.tmp_name', 'Attachment.file.error', 'Attachment.file.size' ); + + // PHP 8.1 introduced another field full_path + if (version_compare(PHP_VERSION, '8.1.0', '>=')) { + $expected[] = 'Attachment.file.full_path'; + } + $this->assertEquals($expected, $this->Form->fields); } diff --git a/lib/Cake/Test/Fixture/AcoActionFixture.php b/lib/Cake/Test/Fixture/AcoActionFixture.php deleted file mode 100644 index df5013f2c8..0000000000 --- a/lib/Cake/Test/Fixture/AcoActionFixture.php +++ /dev/null @@ -1,47 +0,0 @@ - - * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) - * - * Licensed under The MIT License - * For full copyright and license information, please see the LICENSE.txt - * Redistributions of files must retain the above copyright notice - * - * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) - * @link https://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 https://opensource.org/licenses/mit-license.php MIT License - */ - -/** - * Short description for class. - * - * @package Cake.Test.Fixture - */ -class AcoActionFixture extends CakeTestFixture { - -/** - * 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/lib/Cake/Test/Fixture/AcoFixture.php b/lib/Cake/Test/Fixture/AcoFixture.php deleted file mode 100644 index 6cacdd788c..0000000000 --- a/lib/Cake/Test/Fixture/AcoFixture.php +++ /dev/null @@ -1,60 +0,0 @@ - - * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) - * - * Licensed under The MIT License - * For full copyright and license information, please see the LICENSE.txt - * Redistributions of files must retain the above copyright notice - * - * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) - * @link https://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 https://opensource.org/licenses/mit-license.php MIT License - */ - -/** - * Short description for class. - * - * @package Cake.Test.Fixture - */ -class AcoFixture extends CakeTestFixture { - -/** - * 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/lib/Cake/Test/Fixture/AcoTwoFixture.php b/lib/Cake/Test/Fixture/AcoTwoFixture.php deleted file mode 100644 index ef5b8d381c..0000000000 --- a/lib/Cake/Test/Fixture/AcoTwoFixture.php +++ /dev/null @@ -1,58 +0,0 @@ - - * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) - * - * Licensed under The MIT License - * For full copyright and license information, please see the LICENSE.txt - * Redistributions of files must retain the above copyright notice - * - * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) - * @link https://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 https://opensource.org/licenses/mit-license.php MIT License - */ - -/** - * Short description for class. - * - * @package Cake.Test.Fixture - */ -class AcoTwoFixture extends CakeTestFixture { - -/** - * 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/lib/Cake/Test/Fixture/AroFixture.php b/lib/Cake/Test/Fixture/AroFixture.php deleted file mode 100644 index 78d91438d0..0000000000 --- a/lib/Cake/Test/Fixture/AroFixture.php +++ /dev/null @@ -1,52 +0,0 @@ - - * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) - * - * Licensed under The MIT License - * For full copyright and license information, please see the LICENSE.txt - * Redistributions of files must retain the above copyright notice - * - * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) - * @link https://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 https://opensource.org/licenses/mit-license.php MIT License - */ - -/** - * Short description for class. - * - * @package Cake.Test.Fixture - */ -class AroFixture extends CakeTestFixture { - -/** - * 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/lib/Cake/Test/Fixture/AroTwoFixture.php b/lib/Cake/Test/Fixture/AroTwoFixture.php deleted file mode 100644 index fe6e120e53..0000000000 --- a/lib/Cake/Test/Fixture/AroTwoFixture.php +++ /dev/null @@ -1,58 +0,0 @@ - - * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) - * - * Licensed under The MIT License - * For full copyright and license information, please see the LICENSE.txt - * Redistributions of files must retain the above copyright notice - * - * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) - * @link https://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 https://opensource.org/licenses/mit-license.php MIT License - */ - -/** - * Short description for class. - * - * @package Cake.Test.Fixture - */ -class AroTwoFixture extends CakeTestFixture { - -/** - * 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/lib/Cake/Test/Fixture/ArosAcoFixture.php b/lib/Cake/Test/Fixture/ArosAcoFixture.php deleted file mode 100644 index f67dfd644f..0000000000 --- a/lib/Cake/Test/Fixture/ArosAcoFixture.php +++ /dev/null @@ -1,47 +0,0 @@ - - * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) - * - * Licensed under The MIT License - * For full copyright and license information, please see the LICENSE.txt - * Redistributions of files must retain the above copyright notice - * - * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) - * @link https://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 https://opensource.org/licenses/mit-license.php MIT License - */ - -/** - * Short description for class. - * - * @package Cake.Test.Fixture - */ -class ArosAcoFixture extends CakeTestFixture { - -/** - * 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/lib/Cake/Test/Fixture/ArosAcoTwoFixture.php b/lib/Cake/Test/Fixture/ArosAcoTwoFixture.php deleted file mode 100644 index dba6a29c04..0000000000 --- a/lib/Cake/Test/Fixture/ArosAcoTwoFixture.php +++ /dev/null @@ -1,68 +0,0 @@ - - * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) - * - * Licensed under The MIT License - * For full copyright and license information, please see the LICENSE.txt - * Redistributions of files must retain the above copyright notice - * - * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) - * @link https://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 https://opensource.org/licenses/mit-license.php MIT License - */ - -/** - * Short description for class. - * - * @package Cake.Test.Fixture - */ -class ArosAcoTwoFixture extends CakeTestFixture { - -/** - * 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/lib/Cake/Test/bake_compare/Controller/ActionsUsingSessions.ctp b/lib/Cake/Test/bake_compare/Controller/ActionsUsingSessions.ctp deleted file mode 100644 index 34e3fc23f7..0000000000 --- a/lib/Cake/Test/bake_compare/Controller/ActionsUsingSessions.ctp +++ /dev/null @@ -1,90 +0,0 @@ - -/** - * index method - * - * @return void - */ - public function index() { - $this->BakeArticle->recursive = 0; - $this->set('bakeArticles', $this->Paginator->paginate()); - } - -/** - * view method - * - * @throws NotFoundException - * @param string $id - * @return void - */ - public function view($id = null) { - if (!$this->BakeArticle->exists($id)) { - throw new NotFoundException(__('Invalid bake article')); - } - $options = array('conditions' => array('BakeArticle.' . $this->BakeArticle->primaryKey => $id)); - $this->set('bakeArticle', $this->BakeArticle->find('first', $options)); - } - -/** - * add method - * - * @return void - */ - public function add() { - if ($this->request->is('post')) { - $this->BakeArticle->create(); - if ($this->BakeArticle->save($this->request->data)) { - $this->Flash->success(__('The bake article has been saved.')); - return $this->redirect(array('action' => 'index')); - } else { - $this->Flash->error(__('The bake article could not be saved. Please, try again.')); - } - } - $bakeTags = $this->BakeArticle->BakeTag->find('list'); - $this->set(compact('bakeTags')); - } - -/** - * edit method - * - * @throws NotFoundException - * @param string $id - * @return void - */ - public function edit($id = null) { - if (!$this->BakeArticle->exists($id)) { - throw new NotFoundException(__('Invalid bake article')); - } - if ($this->request->is(array('post', 'put'))) { - if ($this->BakeArticle->save($this->request->data)) { - $this->Flash->success(__('The bake article has been saved.')); - return $this->redirect(array('action' => 'index')); - } else { - $this->Flash->error(__('The bake article could not be saved. Please, try again.')); - } - } else { - $options = array('conditions' => array('BakeArticle.' . $this->BakeArticle->primaryKey => $id)); - $this->request->data = $this->BakeArticle->find('first', $options); - } - $bakeTags = $this->BakeArticle->BakeTag->find('list'); - $this->set(compact('bakeTags')); - } - -/** - * delete method - * - * @throws NotFoundException - * @param string $id - * @return void - */ - public function delete($id = null) { - if (!$this->BakeArticle->exists($id)) { - throw new NotFoundException(__('Invalid bake article')); - } - $this->request->allowMethod('post', 'delete'); - if ($this->BakeArticle->delete($id)) { - $this->Flash->success(__('The bake article has been deleted.')); - } else { - $this->Flash->error(__('The bake article could not be deleted. Please, try again.')); - } - return $this->redirect(array('action' => 'index')); - } diff --git a/lib/Cake/Test/bake_compare/Controller/ActionsWithNoSessions.ctp b/lib/Cake/Test/bake_compare/Controller/ActionsWithNoSessions.ctp deleted file mode 100644 index cfdd24f7fd..0000000000 --- a/lib/Cake/Test/bake_compare/Controller/ActionsWithNoSessions.ctp +++ /dev/null @@ -1,83 +0,0 @@ - -/** - * index method - * - * @return void - */ - public function index() { - $this->BakeArticle->recursive = 0; - $this->set('bakeArticles', $this->Paginator->paginate()); - } - -/** - * view method - * - * @throws NotFoundException - * @param string $id - * @return void - */ - public function view($id = null) { - if (!$this->BakeArticle->exists($id)) { - throw new NotFoundException(__('Invalid bake article')); - } - $options = array('conditions' => array('BakeArticle.' . $this->BakeArticle->primaryKey => $id)); - $this->set('bakeArticle', $this->BakeArticle->find('first', $options)); - } - -/** - * add method - * - * @return void - */ - public function add() { - if ($this->request->is('post')) { - $this->BakeArticle->create(); - if ($this->BakeArticle->save($this->request->data)) { - return $this->flash(__('The bake article has been saved.'), array('action' => 'index')); - } - } - $bakeTags = $this->BakeArticle->BakeTag->find('list'); - $this->set(compact('bakeTags')); - } - -/** - * edit method - * - * @throws NotFoundException - * @param string $id - * @return void - */ - public function edit($id = null) { - if (!$this->BakeArticle->exists($id)) { - throw new NotFoundException(__('Invalid bake article')); - } - if ($this->request->is(array('post', 'put'))) { - if ($this->BakeArticle->save($this->request->data)) { - return $this->flash(__('The bake article has been saved.'), array('action' => 'index')); - } - } else { - $options = array('conditions' => array('BakeArticle.' . $this->BakeArticle->primaryKey => $id)); - $this->request->data = $this->BakeArticle->find('first', $options); - } - $bakeTags = $this->BakeArticle->BakeTag->find('list'); - $this->set(compact('bakeTags')); - } - -/** - * delete method - * - * @throws NotFoundException - * @param string $id - * @return void - */ - public function delete($id = null) { - if (!$this->BakeArticle->exists($id)) { - throw new NotFoundException(__('Invalid bake article')); - } - $this->request->allowMethod('post', 'delete'); - if ($this->BakeArticle->delete($id)) { - return $this->flash(__('The bake article has been deleted.'), array('action' => 'index')); - } else { - return $this->flash(__('The bake article could not be deleted. Please, try again.'), array('action' => 'index')); - } - } diff --git a/lib/Cake/Test/bake_compare/Controller/NoActions.ctp b/lib/Cake/Test/bake_compare/Controller/NoActions.ctp deleted file mode 100644 index 54efe9f9f0..0000000000 --- a/lib/Cake/Test/bake_compare/Controller/NoActions.ctp +++ /dev/null @@ -1,27 +0,0 @@ - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - -
Paginator->sort('id'); ?>Paginator->sort('article_id'); ?>Paginator->sort('user_id'); ?>Paginator->sort('comment'); ?>Paginator->sort('published'); ?>Paginator->sort('created'); ?>Paginator->sort('updated'); ?>
  - Html->link($viewTaskComment['Article']['title'], array('controller' => 'view_task_articles', 'action' => 'view', $viewTaskComment['Article']['id'])); ?> -       - Html->link(__('View'), array('action' => 'view', $viewTaskComment['ViewTaskComment']['id'])); ?> - Html->link(__('Edit'), array('action' => 'edit', $viewTaskComment['ViewTaskComment']['id'])); ?> - Form->postLink(__('Delete'), array('action' => 'delete', $viewTaskComment['ViewTaskComment']['id']), array('confirm' => __('Are you sure you want to delete # %s?', $viewTaskComment['ViewTaskComment']['id']))); ?> -
-

- Paginator->counter(array( - 'format' => __('Page {:page} of {:pages}, showing {:current} records out of {:count} total, starting on record {:start}, ending on {:end}') - )); - ?>

-
- Paginator->prev('< ' . __('previous'), array(), null, array('class' => 'prev disabled')); - echo $this->Paginator->numbers(array('separator' => '')); - echo $this->Paginator->next(__('next') . ' >', array(), null, array('class' => 'next disabled')); - ?> -
- -
-

-
    -
  • Html->link(__('New View Task Comment'), array('action' => 'add')); ?>
  • -
  • Html->link(__('List View Task Articles'), array('controller' => 'view_task_articles', 'action' => 'index')); ?>
  • -
  • Html->link(__('New Article'), array('controller' => 'view_task_articles', 'action' => 'add')); ?>
  • -
-
diff --git a/lib/Cake/Test/bootstrap.php b/lib/Cake/Test/bootstrap.php index 52e7069176..a46d6d9819 100644 --- a/lib/Cake/Test/bootstrap.php +++ b/lib/Cake/Test/bootstrap.php @@ -26,4 +26,12 @@ App::uses('ControllerTestCase', 'TestSuite'); App::uses('CakeTestModel', 'TestSuite/Fixture'); -set_error_handler(new \PHPUnit\Util\ErrorHandler(true, true, true, true)); +//set_error_handler(new \PHPUnit\Util\ErrorHandler(true, true, true, true)); + +restore_error_handler(); +restore_error_handler(); + +restore_exception_handler(); +restore_exception_handler(); + + diff --git a/lib/Cake/Test/test_app/Config/acl.ini b/lib/Cake/Test/test_app/Config/acl.ini deleted file mode 100644 index 2e65c6fe7f..0000000000 --- a/lib/Cake/Test/test_app/Config/acl.ini +++ /dev/null @@ -1,57 +0,0 @@ -; -; SVN FILE: $Id$ -;/** -; * Test App Ini Based Acl Config File -; * -; * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) -; * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) -; * -; * Licensed under The MIT License -; * Redistributions of files must retain the above copyright notice. -; * -; * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) -; * @link https://cakephp.org CakePHP(tm) Project -; * @package Cake.Test.TestApp.Config -; * @since CakePHP(tm) v 0.10.0.1076 -; * @license https://opensource.org/licenses/mit-license.php MIT License -; */ - -;------------------------------------- -;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/lib/Cake/Test/test_app/Config/acl.ini.php b/lib/Cake/Test/test_app/Config/acl.ini.php deleted file mode 100644 index 2e65c6fe7f..0000000000 --- a/lib/Cake/Test/test_app/Config/acl.ini.php +++ /dev/null @@ -1,57 +0,0 @@ -; -; SVN FILE: $Id$ -;/** -; * Test App Ini Based Acl Config File -; * -; * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) -; * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) -; * -; * Licensed under The MIT License -; * Redistributions of files must retain the above copyright notice. -; * -; * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) -; * @link https://cakephp.org CakePHP(tm) Project -; * @package Cake.Test.TestApp.Config -; * @since CakePHP(tm) v 0.10.0.1076 -; * @license https://opensource.org/licenses/mit-license.php MIT License -; */ - -;------------------------------------- -;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/lib/Cake/Test/test_app/Config/acl.php b/lib/Cake/Test/test_app/Config/acl.php deleted file mode 100644 index 75d17c36cb..0000000000 --- a/lib/Cake/Test/test_app/Config/acl.php +++ /dev/null @@ -1,70 +0,0 @@ - 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/lib/Cake/Test/test_app/Config/var_test.php b/lib/Cake/Test/test_app/Config/var_test.php index 44c345563d..058b241752 100644 --- a/lib/Cake/Test/test_app/Config/var_test.php +++ b/lib/Cake/Test/test_app/Config/var_test.php @@ -6,7 +6,7 @@ 'Deepest' => 'buried' ) ), - 'TestAcl' => array( + 'TestXXX' => array( 'classname' => 'Original' ) ); diff --git a/lib/Cake/Test/test_app/Config/var_test2.php b/lib/Cake/Test/test_app/Config/var_test2.php index 745b75dbc7..b6be2ecee4 100644 --- a/lib/Cake/Test/test_app/Config/var_test2.php +++ b/lib/Cake/Test/test_app/Config/var_test2.php @@ -6,7 +6,7 @@ 'SecondDeepest' => 'buried2' ) ), - 'TestAcl' => array( + 'TestXXX' => array( 'classname' => 'Overwrite', 'custom' => 'one' ) diff --git a/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/acl.ini.php b/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/acl.ini.php deleted file mode 100644 index 2e65c6fe7f..0000000000 --- a/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/acl.ini.php +++ /dev/null @@ -1,57 +0,0 @@ -; -; SVN FILE: $Id$ -;/** -; * Test App Ini Based Acl Config File -; * -; * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) -; * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) -; * -; * Licensed under The MIT License -; * Redistributions of files must retain the above copyright notice. -; * -; * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) -; * @link https://cakephp.org CakePHP(tm) Project -; * @package Cake.Test.TestApp.Config -; * @since CakePHP(tm) v 0.10.0.1076 -; * @license https://opensource.org/licenses/mit-license.php MIT License -; */ - -;------------------------------------- -;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/lib/Cake/TestSuite/CakeTestCase.php b/lib/Cake/TestSuite/CakeTestCase.php index 17d4156a31..84bfd9fdab 100644 --- a/lib/Cake/TestSuite/CakeTestCase.php +++ b/lib/Cake/TestSuite/CakeTestCase.php @@ -24,6 +24,7 @@ * * @package Cake.TestSuite */ +#[AllowDynamicProperties] abstract class CakeTestCase extends \PHPUnit\Framework\TestCase { /** @@ -52,7 +53,13 @@ abstract class CakeTestCase extends \PHPUnit\Framework\TestCase { */ public $dropTables = true; -/** + /** + * was a dynamic property before + * @var DataSource|null + */ + public ?DataSource $db; + + /** * Configure values to restore at end of test. * * @var array @@ -485,7 +492,7 @@ public function assertTags($string, $expected, $fullDebug = false) { continue; } - list($description, $expressions, $itemNum) = $assertion; + [$description, $expressions, $itemNum] = $assertion; foreach ((array)$expressions as $expression) { if (preg_match(sprintf('/^%s/s', $expression), $string, $match)) { $matches = true; @@ -814,7 +821,7 @@ public function getMockForModel($model, $methods = array(), $config = array()) { $defaults = ClassRegistry::config('Model'); unset($defaults['ds']); - list($plugin, $name) = pluginSplit($model, true); + [$plugin, $name] = pluginSplit($model, true); App::uses($name, $plugin . 'Model'); $config = array_merge($defaults, (array)$config, array('name' => $name)); diff --git a/lib/Cake/TestSuite/ControllerTestCase.php b/lib/Cake/TestSuite/ControllerTestCase.php index 2877fdfd23..95700a97e9 100644 --- a/lib/Cake/TestSuite/ControllerTestCase.php +++ b/lib/Cake/TestSuite/ControllerTestCase.php @@ -31,6 +31,7 @@ */ class ControllerTestDispatcher extends Dispatcher { + public $response = null; /** * The controller to use in the dispatch process * diff --git a/lib/Cake/TestSuite/Fixture/CakeFixtureManager.php b/lib/Cake/TestSuite/Fixture/CakeFixtureManager.php index a6cb396fa6..5ee5ea900f 100644 --- a/lib/Cake/TestSuite/Fixture/CakeFixtureManager.php +++ b/lib/Cake/TestSuite/Fixture/CakeFixtureManager.php @@ -53,6 +53,7 @@ class CakeFixtureManager { * @var array */ protected $_fixtureMap = array(); + protected $_processed = array(); /** * @var null|CakeFixtureManager diff --git a/lib/Cake/TestSuite/Fixture/CakeTestFixture.php b/lib/Cake/TestSuite/Fixture/CakeTestFixture.php index 0bf9d1e8d8..47117202aa 100644 --- a/lib/Cake/TestSuite/Fixture/CakeTestFixture.php +++ b/lib/Cake/TestSuite/Fixture/CakeTestFixture.php @@ -89,8 +89,9 @@ class CakeTestFixture { * @var bool */ public $canUseMemory = true; + private CakeSchema $Schema; -/** + /** * Instantiate the fixture. * * @throws CakeException on invalid datasource usage. @@ -135,7 +136,7 @@ public function init() { $this->Schema->connection = $import['connection']; if (isset($import['model'])) { - list($plugin, $modelClass) = pluginSplit($import['model'], true); + [$plugin, $modelClass] = pluginSplit($import['model'], true); App::uses($modelClass, $plugin . 'Model'); if (!class_exists($modelClass)) { throw new MissingModelException(array('class' => $modelClass)); diff --git a/lib/Cake/Utility/File.php b/lib/Cake/Utility/File.php index 6c4bed1070..87a8644226 100644 --- a/lib/Cake/Utility/File.php +++ b/lib/Cake/Utility/File.php @@ -108,7 +108,7 @@ public function __destruct() { public function create() { $dir = $this->Folder->pwd(); if (is_dir($dir) && is_writable($dir) && !$this->exists()) { - if (touch($this->path)) { + if (@touch($this->path)) { return true; } } diff --git a/lib/Cake/Utility/Hash.php b/lib/Cake/Utility/Hash.php index 84c706aeed..37c297b278 100644 --- a/lib/Cake/Utility/Hash.php +++ b/lib/Cake/Utility/Hash.php @@ -561,7 +561,7 @@ public static function check(array $data, $path) { * @return array Filtered array * @link https://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::filter */ - public static function filter(array $data, $callback = array('self', '_filter')) { + public static function filter(array $data, $callback = array(self::class, '_filter')) { foreach ($data as $k => $v) { if (is_array($v)) { $data[$k] = static::filter($v, $callback); diff --git a/lib/Cake/Utility/Inflector.php b/lib/Cake/Utility/Inflector.php index 80c5c09ae9..680a13f982 100644 --- a/lib/Cake/Utility/Inflector.php +++ b/lib/Cake/Utility/Inflector.php @@ -500,7 +500,7 @@ public static function underscore($camelCasedWord) { */ public static function humanize($lowerCaseAndUnderscoredWord) { if (!($result = static::_cache(__FUNCTION__, $lowerCaseAndUnderscoredWord))) { - $result = explode(' ', str_replace('_', ' ', $lowerCaseAndUnderscoredWord)); + $result = explode(' ', str_replace('_', ' ', (string) $lowerCaseAndUnderscoredWord)); foreach ($result as &$word) { $word = mb_strtoupper(mb_substr($word, 0, 1)) . mb_substr($word, 1); } diff --git a/lib/Cake/View/Helper.php b/lib/Cake/View/Helper.php index ac8faf8183..801ff3e2e9 100644 --- a/lib/Cake/View/Helper.php +++ b/lib/Cake/View/Helper.php @@ -569,6 +569,7 @@ protected function _confirm($message, $okCode, $cancelCode = '', $options = arra public function setEntity($entity, $setScope = false) { if ($entity === null) { $this->_modelScope = false; + return; } if ($setScope === true) { $this->_modelScope = $entity; diff --git a/lib/Cake/View/Helper/FormHelper.php b/lib/Cake/View/Helper/FormHelper.php index 376ce8d39d..dfc64fd845 100644 --- a/lib/Cake/View/Helper/FormHelper.php +++ b/lib/Cake/View/Helper/FormHelper.php @@ -2300,7 +2300,7 @@ public function day($fieldName = null, $attributes = array()) { $attributes += array('empty' => true, 'value' => null); $attributes = $this->_dateTimeSelected('day', $fieldName, $attributes); - if (strlen($attributes['value']) > 2) { + if (strlen((string) $attributes['value']) > 2) { $date = date_create($attributes['value']); $attributes['value'] = null; if ($date) { @@ -2396,7 +2396,7 @@ public function month($fieldName, $attributes = array()) { $attributes += array('empty' => true, 'value' => null); $attributes = $this->_dateTimeSelected('month', $fieldName, $attributes); - if (strlen($attributes['value']) > 2) { + if (strlen((string)$attributes['value']) > 2) { $date = date_create($attributes['value']); $attributes['value'] = null; if ($date) { @@ -2767,7 +2767,7 @@ protected function _getDateTimeValue($value, $timeFormat) { } if (is_numeric($value)) { - $value = strftime('%Y-%m-%d %H:%M:%S', $value); + $value = date('Y-m-d H:i:s', $value); } $meridian = 'am'; $pos = strpos($value, '-'); diff --git a/lib/Cake/basics.php b/lib/Cake/basics.php index 10d965c1cf..9ffbd01226 100644 --- a/lib/Cake/basics.php +++ b/lib/Cake/basics.php @@ -323,7 +323,7 @@ function env($key) { if (isset($_SERVER['HTTPS'])) { return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'); } - return (strpos(env('SCRIPT_URI'), 'https://') === 0); + return (strpos((string) env('SCRIPT_URI'), 'https://') === 0); } if ($key === 'SCRIPT_NAME') { @@ -488,7 +488,7 @@ function cache($path, $data = null, $expires = '+1 day', $target = 'cache') { */ function clearCache($params = null, $type = 'views', $ext = '.php') { if (is_string($params) || $params === null) { - $params = preg_replace('/\/\//', '/', $params); + $params = preg_replace('/\/\//', '/', (string) $params); $cache = CACHE . $type . DS . $params; if (is_file($cache . $ext)) { diff --git a/phpunit.xml b/phpunit.xml index 92b96370ee..e92bb2c45a 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -3,6 +3,11 @@ xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.5/phpunit.xsd" bootstrap="lib/Cake/Test/bootstrap.php" backupGlobals="true" + convertErrorsToExceptions="true" + convertNoticesToExceptions="false" + convertWarningsToExceptions="true" + failOnWarning="false" + verbose="true" colors="true" stderr="true" stopOnFailure="false" @@ -19,6 +24,7 @@ + diff --git a/rector.php b/rector.php index dcd4c19765..bff4ce4460 100644 --- a/rector.php +++ b/rector.php @@ -14,13 +14,14 @@ return static function (RectorConfig $rectorConfig): void { $rectorConfig->paths([ - __DIR__ . '/app', - __DIR__ . '/lib', - __DIR__ . '/plugins', +// __DIR__ . '/app', + __DIR__ . '/lib/Cake', +// __DIR__ . '/plugins', ]); $rectorConfig->parallel(360, 8); + $rectorConfig->phpVersion(PhpVersion::PHP_80); // DEFINE RULES (Single & Sets) // Rule Overview: https://github.com/rectorphp/rector/blob/main/docs/rector_rules_overview.md // Register a single rule @@ -36,7 +37,7 @@ // SetList::PHP_73, // PHP5x + PHP70,1,2,3 - LevelSetList::UP_TO_PHP_73, + LevelSetList::UP_TO_PHP_82, // PHPUnitSetList::PHPUNIT_60, // PHPUnitSetList::PHPUNIT_70, @@ -50,12 +51,7 @@ CountOnNullRector::class, StringClassNameToClassConstantRector::class, __DIR__ . '/app/Test/Case/ModelTestRunFirst/data', - - // Count on Null --> Should be a dedicated commit, where we can refactor return types first -// => [ -// __DIR__ . '/app/Test', -// __DIR__ . '/app/Plugin/*/Test' -// ] + __DIR__ . '/lib/Cake/Test', ]); $rectorConfig->autoloadPaths([