diff --git a/.travis.yml b/.travis.yml index 5af60d8d8..f7705b817 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,6 +10,16 @@ env: - DB=pgsql - DB=sqlite +matrix: + allow_failures: + - php: 5.4 + env: + - PHPCS=1 + include: + - php: 5.4 + env: + - PHPCS=1 + before_script: - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'CREATE DATABASE cakephp_test;'; fi" - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'CREATE DATABASE cakephp_test2;'; fi" @@ -23,6 +33,9 @@ before_script: server.listen(80, 'localhost'); console.log('TCP server listening on port 80 at localhost.');" > app/tmp/socket.js - sudo node ./app/tmp/socket.js & + - pear channel-discover pear.cakephp.org + - pear install --alldeps cakephp/CakePHP_CodeSniffer + - phpenv rehash - set +H - echo " app/Config/database.php script: - - ./lib/Cake/Console/cake test core AllTests --stderr + - sh -c "if [ '$PHPCS' != '1' ]; then ./lib/Cake/Console/cake test core AllTests --stderr; else phpcs --extensions=php --standard=CakePHP ./lib/Cake; fi" notifications: email: false \ No newline at end of file diff --git a/app/Config/Schema/i18n.php b/app/Config/Schema/i18n.php index 8de0052dd..08aab843b 100644 --- a/app/Config/Schema/i18n.php +++ b/app/Config/Schema/i18n.php @@ -19,14 +19,17 @@ * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ +// @codingStandardsIgnoreStart + /* * * Using the Schema command line utility * cake schema run create i18n - * */ class i18nSchema extends CakeSchema { +// @codingStandardsIgnoreEnd + public $name = 'i18n'; public function before($event = array()) { diff --git a/app/Config/acl.php b/app/Config/acl.php index 21f8ddaa7..3df822ab4 100644 --- a/app/Config/acl.php +++ b/app/Config/acl.php @@ -22,18 +22,18 @@ /** * Example * ------- - * + * * Assumptions: * - * 1. In your application you created a User model with the following properties: + * 1. In your application you created a User model with the following properties: * username, group_id, password, email, firstname, lastname and so on. - * 2. You configured AuthComponent to authorize actions via - * $this->Auth->authorize = array('Actions' => array('actionPath' => 'controllers/'),...) - * + * 2. You configured AuthComponent to authorize actions via + * $this->Auth->authorize = array('Actions' => array('actionPath' => 'controllers/'),...) + * * Now, when a user (i.e. jeff) authenticates successfully and requests a controller action (i.e. /invoices/delete) - * that is not allowed by default (e.g. via $this->Auth->allow('edit') in the Invoices controller) then AuthComponent - * will ask the configured ACL interface if access is granted. Under the assumptions 1. and 2. this will be - * done via a call to Acl->check() with + * 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, ...)) * @@ -42,7 +42,7 @@ * '/controllers/invoices/delete' * * as ACO. - * + * * If the configured map looks like * * $config['map'] = array( @@ -50,17 +50,17 @@ * '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 + * 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, @@ -68,7 +68,7 @@ * '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: * @@ -87,10 +87,10 @@ * ), * ); * - * 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 + * 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 + * 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. @@ -101,7 +101,7 @@ /** * The role map defines how to resolve the user record from your application - * to the roles you defined in the roles configuration. + * to the roles you defined in the roles configuration. */ $config['map'] = array( 'User' => 'User/username', diff --git a/app/Config/bootstrap.php b/app/Config/bootstrap.php index bcc50f6c4..dd7a596da 100644 --- a/app/Config/bootstrap.php +++ b/app/Config/bootstrap.php @@ -2,7 +2,7 @@ /** * This file is loaded automatically by the app/webroot/index.php file after core.php * - * This file should load/create any application wide configuration settings, such as + * This file should load/create any application wide configuration settings, such as * Caching, Logging, loading additional configuration files. * * You should also use this file to include any files that provide global functions/constants diff --git a/app/Config/core.php b/app/Config/core.php index 4bbfabe6e..99198539f 100644 --- a/app/Config/core.php +++ b/app/Config/core.php @@ -226,7 +226,7 @@ Configure::write('Acl.database', 'default'); /** - * Uncomment this line and correct your server timezone to fix + * Uncomment this line and correct your server timezone to fix * any date & time related errors. */ //date_default_timezone_set('UTC'); @@ -236,7 +236,7 @@ * If running via cli - apc is disabled by default. ensure it's available and enabled in this case * * Note: 'default' and other application caches should be configured in app/Config/bootstrap.php. - * Please check the comments in boostrap.php for more info on the cache engines available + * Please check the comments in boostrap.php for more info on the cache engines available * and their setttings. */ $engine = 'File'; diff --git a/app/Config/routes.php b/app/Config/routes.php index 32151d27c..c68cc3e4a 100644 --- a/app/Config/routes.php +++ b/app/Config/routes.php @@ -32,7 +32,7 @@ Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display')); /** - * Load all plugin routes. See the CakePlugin documentation on + * Load all plugin routes. See the CakePlugin documentation on * how to customize the loading of plugin routes. */ CakePlugin::routes(); diff --git a/lib/Cake/Cache/CacheEngine.php b/lib/Cake/Cache/CacheEngine.php index 6994701f4..9daf4d7c0 100644 --- a/lib/Cake/Cache/CacheEngine.php +++ b/lib/Cake/Cache/CacheEngine.php @@ -65,7 +65,7 @@ abstract class CacheEngine { * Garbage collection * * Permanently remove all expired and deleted data - * + * * @param integer $expires [optional] An expires timestamp, invalidataing all data before. * @return void */ diff --git a/lib/Cake/Cache/Engine/FileEngine.php b/lib/Cake/Cache/Engine/FileEngine.php index 9388fafb9..da68c398c 100644 --- a/lib/Cake/Cache/Engine/FileEngine.php +++ b/lib/Cake/Cache/Engine/FileEngine.php @@ -93,7 +93,7 @@ class FileEngine extends CacheEngine { /** * Garbage collection. Permanently remove all expired and deleted data - * + * * @param integer $expires [optional] An expires timestamp, invalidataing all data before. * @return boolean True if garbage collection was successful, false on failure */ diff --git a/lib/Cake/Console/Command/Task/TemplateTask.php b/lib/Cake/Console/Command/Task/TemplateTask.php index ffe993ce0..69b4cdd39 100644 --- a/lib/Cake/Console/Command/Task/TemplateTask.php +++ b/lib/Cake/Console/Command/Task/TemplateTask.php @@ -56,7 +56,7 @@ class TemplateTask extends AppShell { * * 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() { diff --git a/lib/Cake/Console/Command/TestShell.php b/lib/Cake/Console/Command/TestShell.php index f14c51874..c96279305 100644 --- a/lib/Cake/Console/Command/TestShell.php +++ b/lib/Cake/Console/Command/TestShell.php @@ -114,7 +114,7 @@ class TestShell extends Shell { ))->addOption('stop-on-failure', array( 'help' => __d('cake_console', 'Stop execution upon first failure.'), 'boolean' => true - ))->addOption('stop-on-skipped ', array( + ))->addOption('stop-on-skipped', array( 'help' => __d('cake_console', 'Stop execution upon first skipped test.'), 'boolean' => true ))->addOption('stop-on-incomplete', array( @@ -132,7 +132,7 @@ class TestShell extends Shell { ))->addOption('no-globals-backup', array( 'help' => __d('cake_console', 'Do not backup and restore $GLOBALS for each test.'), 'boolean' => true - ))->addOption('static-backup ', array( + ))->addOption('static-backup', array( 'help' => __d('cake_console', 'Backup and restore static attributes for each test.'), 'boolean' => true ))->addOption('syntax-check', array( @@ -335,8 +335,8 @@ class TestShell extends Shell { * Find the test case for the passed file. The file could itself be a test. * * @param string $file - * @param string $category - * @param boolean $throwOnMissingFile + * @param string $category + * @param boolean $throwOnMissingFile * @access protected * @return array(type, case) * @throws Exception diff --git a/lib/Cake/Console/ShellDispatcher.php b/lib/Cake/Console/ShellDispatcher.php index 162e8f508..426e73485 100644 --- a/lib/Cake/Console/ShellDispatcher.php +++ b/lib/Cake/Console/ShellDispatcher.php @@ -215,7 +215,7 @@ class ShellDispatcher { return $Shell->main(); } } - + throw new MissingShellMethodException(array('shell' => $shell, 'method' => $command)); } diff --git a/lib/Cake/Console/Templates/skel/Config/Schema/i18n.php b/lib/Cake/Console/Templates/skel/Config/Schema/i18n.php index 1a29ffd98..1b8b08735 100644 --- a/lib/Cake/Console/Templates/skel/Config/Schema/i18n.php +++ b/lib/Cake/Console/Templates/skel/Config/Schema/i18n.php @@ -21,14 +21,17 @@ * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ +// @codingStandardsIgnoreStart + /* * * Using the Schema command line utility * cake schema run create i18n - * */ class i18nSchema extends CakeSchema { +// @codingStandardsIgnoreEnd + public $name = 'i18n'; public function before($event = array()) { diff --git a/lib/Cake/Console/Templates/skel/Config/bootstrap.php b/lib/Cake/Console/Templates/skel/Config/bootstrap.php index 786011ee5..580f351d0 100644 --- a/lib/Cake/Console/Templates/skel/Config/bootstrap.php +++ b/lib/Cake/Console/Templates/skel/Config/bootstrap.php @@ -98,11 +98,11 @@ Configure::write('Dispatcher.filters', array( App::uses('CakeLog', 'Log'); CakeLog::config('debug', array( 'engine' => 'FileLog', - 'scopes' => array('notice', 'info', 'debug'), + 'types' => array('notice', 'info', 'debug'), 'file' => 'debug', )); CakeLog::config('error', array( 'engine' => 'FileLog', - 'scopes' => array('warning', 'error', 'critical', 'alert', 'emergency'), + 'types' => array('warning', 'error', 'critical', 'alert', 'emergency'), 'file' => 'error', )); diff --git a/lib/Cake/Console/Templates/skel/Config/core.php b/lib/Cake/Console/Templates/skel/Config/core.php index c53e2fd02..7720e9ed6 100644 --- a/lib/Cake/Console/Templates/skel/Config/core.php +++ b/lib/Cake/Console/Templates/skel/Config/core.php @@ -226,7 +226,7 @@ Configure::write('Acl.database', 'default'); /** - * Uncomment this line and correct your server timezone to fix + * Uncomment this line and correct your server timezone to fix * any date & time related errors. */ //date_default_timezone_set('UTC'); diff --git a/lib/Cake/Controller/CakeErrorController.php b/lib/Cake/Controller/CakeErrorController.php index 577864881..c1835fd6e 100644 --- a/lib/Cake/Controller/CakeErrorController.php +++ b/lib/Cake/Controller/CakeErrorController.php @@ -19,6 +19,8 @@ * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ +App::uses('AppController', 'Controller'); + /** * Error Handling Controller * @@ -50,7 +52,11 @@ class CakeErrorController extends AppController { */ public function __construct($request = null, $response = null) { parent::__construct($request, $response); - if (count(Router::extensions())) { + if ( + count(Router::extensions()) && + !array_key_exists('RequestHandler', $this->components) && + !in_array('RequestHandler', $this->components, true) + ) { $this->components[] = 'RequestHandler'; } $this->constructClasses(); diff --git a/lib/Cake/Controller/Component.php b/lib/Cake/Controller/Component.php index 876174e8c..42815e534 100644 --- a/lib/Cake/Controller/Component.php +++ b/lib/Cake/Controller/Component.php @@ -120,7 +120,7 @@ class Component extends Object { } /** - * Called before the Controller::beforeRender(), and before + * Called before the Controller::beforeRender(), and before * the view class is loaded, and before Controller::render() * * @param Controller $controller Controller with components to beforeRender diff --git a/lib/Cake/Controller/Component/Acl/IniAcl.php b/lib/Cake/Controller/Component/Acl/IniAcl.php index 8810668cc..d915443fb 100644 --- a/lib/Cake/Controller/Component/Acl/IniAcl.php +++ b/lib/Cake/Controller/Component/Acl/IniAcl.php @@ -143,7 +143,7 @@ class IniAcl extends Object implements AclInterface { } /** - * Parses an INI file and returns an array that reflects the + * Parses an INI file and returns an array that reflects the * INI file's section structure. Double-quote friendly. * * @param string $filename File diff --git a/lib/Cake/Controller/Component/Acl/PhpAcl.php b/lib/Cake/Controller/Component/Acl/PhpAcl.php index d63217857..bd9c7302e 100644 --- a/lib/Cake/Controller/Component/Acl/PhpAcl.php +++ b/lib/Cake/Controller/Component/Acl/PhpAcl.php @@ -18,7 +18,7 @@ */ /** - * PhpAcl implements an access control system using a plain PHP configuration file. + * PhpAcl implements an access control system using a plain PHP configuration file. * An example file can be found in app/Config/acl.php * * @package Cake.Controller.Component.Acl @@ -46,7 +46,7 @@ class PhpAcl extends Object implements AclInterface { /** * Aco Object - * + * * @var PhpAco */ public $Aco = null; @@ -65,8 +65,8 @@ class PhpAcl extends Object implements AclInterface { /** * Initialize method - * - * @param AclComponent $Component Component instance + * + * @param AclComponent $Component Component instance * @return void */ public function initialize(Component $Component) { @@ -199,7 +199,7 @@ class PhpAco { /** * map modifiers for ACO paths to their respective PCRE pattern - * + * * @var array */ public static $modifiers = array( @@ -263,7 +263,7 @@ class PhpAco { /** * allow/deny ARO access to ARO * - * @return void + * @return void */ public function access($aro, $aco, $action, $type = 'deny') { $aco = $this->resolve($aco); @@ -315,7 +315,7 @@ class PhpAco { * * @param array $allow ACO allow rules * @param array $deny ACO deny rules - * @return void + * @return void */ public function build(array $allow, array $deny = array()) { $this->_tree = array(); @@ -347,7 +347,7 @@ class PhpAco { class PhpAro { /** - * role to resolve to when a provided ARO is not listed in + * role to resolve to when a provided ARO is not listed in * the internal tree * * @var string @@ -357,12 +357,12 @@ class PhpAro { /** * map external identifiers. E.g. if * - * array('User' => array('username' => 'jeff', 'role' => 'editor')) + * array('User' => array('username' => 'jeff', 'role' => 'editor')) * - * is passed as an ARO to one of the methods of AclComponent, PhpAcl + * 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. - * + * configuration file. + * * @var array * @see app/Config/acl.php */ @@ -373,7 +373,7 @@ class PhpAro { /** * aliases to map - * + * * @var array */ public $aliases = array(); @@ -398,9 +398,9 @@ class PhpAro { * 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 + * 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 */ @@ -425,7 +425,7 @@ class PhpAro { /** * resolve an ARO identifier to an internal ARO string using - * the internal mapping information. + * 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) @@ -527,7 +527,7 @@ class PhpAro { * build an ARO tree structure for internal processing * * @param array $aros array of AROs as key and their inherited AROs as values - * @return void + * @return void */ public function build(array $aros) { $this->_tree = array(); diff --git a/lib/Cake/Controller/Component/Auth/BaseAuthenticate.php b/lib/Cake/Controller/Component/Auth/BaseAuthenticate.php index d9dc7248f..e5bd08cfe 100644 --- a/lib/Cake/Controller/Component/Auth/BaseAuthenticate.php +++ b/lib/Cake/Controller/Component/Auth/BaseAuthenticate.php @@ -84,7 +84,7 @@ abstract class BaseAuthenticate { } $result = ClassRegistry::init($userModel)->find('first', array( 'conditions' => $conditions, - 'recursive' => (int)$this->settings['recursive'], + 'recursive' => $this->settings['recursive'], 'contain' => $this->settings['contain'], )); if (empty($result) || empty($result[$model])) { diff --git a/lib/Cake/Controller/Component/Auth/DigestAuthenticate.php b/lib/Cake/Controller/Component/Auth/DigestAuthenticate.php index bdea7d8aa..21c353339 100644 --- a/lib/Cake/Controller/Component/Auth/DigestAuthenticate.php +++ b/lib/Cake/Controller/Component/Auth/DigestAuthenticate.php @@ -68,7 +68,7 @@ class DigestAuthenticate extends BaseAuthenticate { * - `realm` The realm authentication is for, Defaults to the servername. * - `nonce` A nonce used for authentication. Defaults to `uniqid()`. * - `qop` Defaults to auth, no other values are supported at this time. - * - `opaque` A string that must be returned unchanged by clients. + * - `opaque` A string that must be returned unchanged by clients. * Defaults to `md5($settings['realm'])` * * @var array @@ -170,7 +170,7 @@ class DigestAuthenticate extends BaseAuthenticate { } $result = ClassRegistry::init($userModel)->find('first', array( 'conditions' => $conditions, - 'recursive' => (int)$this->settings['recursive'] + 'recursive' => $this->settings['recursive'] )); if (empty($result) || empty($result[$model])) { return false; diff --git a/lib/Cake/Controller/Component/CookieComponent.php b/lib/Cake/Controller/Component/CookieComponent.php index f314c42fa..1d962bc28 100644 --- a/lib/Cake/Controller/Component/CookieComponent.php +++ b/lib/Cake/Controller/Component/CookieComponent.php @@ -155,7 +155,7 @@ class CookieComponent extends Component { /** * A reference to the Controller's CakeResponse object - * + * * @var CakeResponse */ protected $_response = null; diff --git a/lib/Cake/Controller/Component/SecurityComponent.php b/lib/Cake/Controller/Component/SecurityComponent.php index 3b5eb8669..907b43a8f 100644 --- a/lib/Cake/Controller/Component/SecurityComponent.php +++ b/lib/Cake/Controller/Component/SecurityComponent.php @@ -23,7 +23,7 @@ App::uses('Hash', 'Utility'); App::uses('Security', 'Utility'); /** - * The Security Component creates an easy way to integrate tighter security in + * The Security Component creates an easy way to integrate tighter security in * your application. It provides methods for various tasks like: * * - Restricting which HTTP methods your application accepts. diff --git a/lib/Cake/Controller/Component/SessionComponent.php b/lib/Cake/Controller/Component/SessionComponent.php index ed42bff24..0bcdb7fa6 100644 --- a/lib/Cake/Controller/Component/SessionComponent.php +++ b/lib/Cake/Controller/Component/SessionComponent.php @@ -21,8 +21,8 @@ App::uses('Component', 'Controller'); App::uses('CakeSession', 'Model/Datasource'); /** - * The CakePHP SessionComponent provides a way to persist client data between - * page requests. It acts as a wrapper for the `$_SESSION` as well as providing + * The CakePHP SessionComponent provides a way to persist client data between + * page requests. It acts as a wrapper for the `$_SESSION` as well as providing * convenience methods for several `$_SESSION` related functions. * * @package Cake.Controller.Component diff --git a/lib/Cake/Controller/Controller.php b/lib/Cake/Controller/Controller.php index 978dade84..8b3098998 100644 --- a/lib/Cake/Controller/Controller.php +++ b/lib/Cake/Controller/Controller.php @@ -796,7 +796,7 @@ class Controller extends Object implements CakeEventListener { * @return array Array with keys url, status and exit */ protected function _parseBeforeRedirect($response, $url, $status, $exit) { - if (is_array($response) && isset($response[0])) { + if (is_array($response) && array_key_exists(0, $response)) { foreach ($response as $resp) { if (is_array($resp) && isset($resp['url'])) { extract($resp, EXTR_OVERWRITE); diff --git a/lib/Cake/Core/CakePlugin.php b/lib/Cake/Core/CakePlugin.php index 5242c9f98..814f36b32 100644 --- a/lib/Cake/Core/CakePlugin.php +++ b/lib/Cake/Core/CakePlugin.php @@ -18,7 +18,7 @@ */ /** - * CakePlugin is responsible for loading and unloading plugins. It also can + * CakePlugin is responsible for loading and unloading plugins. It also can * retrieve plugin paths and load their bootstrap and routes files. * * @package Cake.Core diff --git a/lib/Cake/Core/Object.php b/lib/Cake/Core/Object.php index d95855788..15a58309d 100644 --- a/lib/Cake/Core/Object.php +++ b/lib/Cake/Core/Object.php @@ -73,9 +73,13 @@ class Object { $extra['autoRender'] = 1; unset($extra[$index]); } - if (is_array($url) && !isset($extra['url'])) { + $arrayUrl = is_array($url); + if ($arrayUrl && !isset($extra['url'])) { $extra['url'] = array(); } + if ($arrayUrl && !isset($extra['data'])) { + $extra['data'] = array(); + } $extra = array_merge(array('autoRender' => 0, 'return' => 1, 'bare' => 1, 'requested' => 1), $extra); $data = isset($extra['data']) ? $extra['data'] : null; unset($extra['data']); @@ -88,11 +92,12 @@ class Object { } elseif (is_array($url)) { $params = $url + array('pass' => array(), 'named' => array(), 'base' => false); $params = array_merge($params, $extra); - $request = new CakeRequest(Router::reverse($params), false); + $request = new CakeRequest(Router::reverse($params)); } if (isset($data)) { $request->data = $data; } + $dispatcher = new Dispatcher(); $result = $dispatcher->dispatch($request, new CakeResponse(), $extra); Router::popRequest(); diff --git a/lib/Cake/Error/ErrorHandler.php b/lib/Cake/Error/ErrorHandler.php index dcc0973c9..87a605835 100644 --- a/lib/Cake/Error/ErrorHandler.php +++ b/lib/Cake/Error/ErrorHandler.php @@ -22,7 +22,6 @@ App::uses('Debugger', 'Utility'); App::uses('CakeLog', 'Log'); App::uses('ExceptionRenderer', 'Error'); -App::uses('AppController', 'Controller'); /** * diff --git a/lib/Cake/Error/ExceptionRenderer.php b/lib/Cake/Error/ExceptionRenderer.php index a404d3be8..3be08d26c 100644 --- a/lib/Cake/Error/ExceptionRenderer.php +++ b/lib/Cake/Error/ExceptionRenderer.php @@ -142,15 +142,14 @@ class ExceptionRenderer { * @return Controller */ protected function _getController($exception) { + App::uses('AppController', 'Controller'); App::uses('CakeErrorController', 'Controller'); if (!$request = Router::getRequest(true)) { $request = new CakeRequest(); } $response = new CakeResponse(array('charset' => Configure::read('App.encoding'))); try { - if (class_exists('AppController')) { - $controller = new CakeErrorController($request, $response); - } + $controller = new CakeErrorController($request, $response); } catch (Exception $e) { } if (empty($controller)) { diff --git a/lib/Cake/Event/CakeEvent.php b/lib/Cake/Event/CakeEvent.php index 52de3cf23..c70d4f816 100644 --- a/lib/Cake/Event/CakeEvent.php +++ b/lib/Cake/Event/CakeEvent.php @@ -27,7 +27,7 @@ class CakeEvent { /** * Name of the event - * + * * @var string $name */ protected $_name = null; diff --git a/lib/Cake/Event/CakeEventManager.php b/lib/Cake/Event/CakeEventManager.php index 252364d4c..aacd537c9 100644 --- a/lib/Cake/Event/CakeEventManager.php +++ b/lib/Cake/Event/CakeEventManager.php @@ -50,7 +50,7 @@ class CakeEventManager { protected $_listeners = array(); /** - * Internal flag to distinguish a common manager from the sigleton + * Internal flag to distinguish a common manager from the sigleton * * @var boolean */ @@ -64,7 +64,7 @@ class CakeEventManager { * * If called with a first params, it will be set as the globally available instance * - * @param CakeEventManager $manager + * @param CakeEventManager $manager * @return CakeEventManager the global event manager */ public static function instance($manager = null) { @@ -80,7 +80,7 @@ class CakeEventManager { } /** - * Adds a new listener to an event. Listeners + * Adds a new listener to an event. Listeners * * @param callback|CakeEventListener $callable PHP valid callback type or instance of CakeEventListener to be called * when the event named with $eventKey is triggered. If a CakeEventListener instances is passed, then the `implementedEvents` diff --git a/lib/Cake/I18n/I18n.php b/lib/Cake/I18n/I18n.php index 7678ba6ae..862414b7c 100644 --- a/lib/Cake/I18n/I18n.php +++ b/lib/Cake/I18n/I18n.php @@ -24,13 +24,6 @@ App::uses('CakePlugin', 'Core'); App::uses('L10n', 'I18n'); App::uses('Multibyte', 'I18n'); -if (function_exists('mb_internal_encoding')) { - $encoding = Configure::read('App.encoding'); - if (!empty($encoding)) { - mb_internal_encoding($encoding); - } -} - /** * I18n handles translation of Text and time format strings. * diff --git a/lib/Cake/I18n/Multibyte.php b/lib/Cake/I18n/Multibyte.php index b741ef4d6..eb4847aa4 100644 --- a/lib/Cake/I18n/Multibyte.php +++ b/lib/Cake/I18n/Multibyte.php @@ -1008,7 +1008,8 @@ class Multibyte { if ($charset == 'UTF-8') { $parts = array(); $maxchars = floor(($length * 3) / 4); - while (strlen($string) > $maxchars) { + $stringLength = strlen($string); + while ($stringLength > $maxchars) { $i = (int)$maxchars; $test = ord($string[$i]); while ($test >= 128 && $test <= 191) { @@ -1017,6 +1018,7 @@ class Multibyte { } $parts[] = base64_encode(substr($string, 0, $i)); $string = substr($string, $i); + $stringLength = strlen($string); } $parts[] = base64_encode($string); $string = implode($spacer, $parts); diff --git a/lib/Cake/Log/CakeLog.php b/lib/Cake/Log/CakeLog.php index ad5a411c1..776ea9e6f 100644 --- a/lib/Cake/Log/CakeLog.php +++ b/lib/Cake/Log/CakeLog.php @@ -67,6 +67,7 @@ App::uses('LogEngineCollection', 'Log'); * application. By using scopes you can control logging for each part * of your application and still keep standard log levels. * + * * See CakeLog::config() and CakeLog::write() for more information * on scopes * @@ -173,7 +174,10 @@ class CakeLog { * * The above logger will only capture log entries made in the * `payment` and `order` scopes. All other scopes including the - * undefined scope will be ignored. + * undefined scope will be ignored. Its important to remember that + * when using scopes you must also define the `types` of log messages + * that a logger will handle. Failing to do so will result in the logger + * catching all log messages even if the scope is incorrect. * * @param string $key The keyname for this logger, used to remove the * logger later. @@ -422,24 +426,29 @@ class CakeLog { $logged = false; foreach (self::$_Collection->enabled() as $streamName) { $logger = self::$_Collection->{$streamName}; - $types = null; - $scopes = array(); + $types = $scopes = $config = array(); if ($logger instanceof BaseLog) { $config = $logger->config(); - if (isset($config['types'])) { - $types = $config['types']; - } - if (isset($config['scopes'])) { - $scopes = $config['scopes']; - } } - if (is_string($scope)) { - $inScope = in_array($scope, $scopes); - } else { - $intersect = array_intersect($scope, $scopes); - $inScope = !empty($intersect); + if (isset($config['types'])) { + $types = $config['types']; } - if (empty($types) || in_array($type, $types) || in_array($type, $scopes) && $inScope) { + if (isset($config['scopes'])) { + $scopes = $config['scopes']; + } + $inScope = (count(array_intersect((array)$scope, $scopes)) > 0); + $correctLevel = in_array($type, $types); + + if ( + // No config is a catch all (bc mode) + (empty($types) && empty($scopes)) || + // BC layer for mixing scope & level + (in_array($type, $scopes)) || + // no scopes, but has level + (empty($scopes) && $correctLevel) || + // exact scope + level + ($correctLevel && $inScope) + ) { $logger->write($type, $message); $logged = true; } diff --git a/lib/Cake/Model/Behavior/ContainableBehavior.php b/lib/Cake/Model/Behavior/ContainableBehavior.php index bb33eaf46..799f6e238 100644 --- a/lib/Cake/Model/Behavior/ContainableBehavior.php +++ b/lib/Cake/Model/Behavior/ContainableBehavior.php @@ -20,8 +20,8 @@ */ /** - * Behavior to allow for dynamic and atomic manipulation of a Model's associations - * used for a find call. Most useful for limiting the amount of associations and + * Behavior to allow for dynamic and atomic manipulation of a Model's associations + * used for a find call. Most useful for limiting the amount of associations and * data returned. * * @package Cake.Model.Behavior @@ -91,21 +91,25 @@ class ContainableBehavior extends ModelBehavior { */ public function beforeFind(Model $Model, $query) { $reset = (isset($query['reset']) ? $query['reset'] : true); - $noContain = ( - (isset($this->runtime[$Model->alias]['contain']) && empty($this->runtime[$Model->alias]['contain'])) || - (isset($query['contain']) && empty($query['contain'])) - ); + $noContain = false; $contain = array(); + if (isset($this->runtime[$Model->alias]['contain'])) { + $noContain = empty($this->runtime[$Model->alias]['contain']); $contain = $this->runtime[$Model->alias]['contain']; unset($this->runtime[$Model->alias]['contain']); } + if (isset($query['contain'])) { - $contain = array_merge($contain, (array)$query['contain']); + $noContain = $noContain || empty($query['contain']); + if ($query['contain'] !== false) { + $contain = array_merge($contain, (array)$query['contain']); + } } + $noContain = $noContain && empty($contain); + if ( - $noContain || !$contain || in_array($contain, array(null, false), true) || - (isset($contain[0]) && $contain[0] === null) + $noContain || empty($contain) || (isset($contain[0]) && $contain[0] === null) ) { if ($noContain) { $query['recursive'] = -1; diff --git a/lib/Cake/Model/Behavior/TranslateBehavior.php b/lib/Cake/Model/Behavior/TranslateBehavior.php index dd1243b91..01a2c0d53 100644 --- a/lib/Cake/Model/Behavior/TranslateBehavior.php +++ b/lib/Cake/Model/Behavior/TranslateBehavior.php @@ -383,6 +383,21 @@ class TranslateBehavior extends ModelBehavior { $this->runtime[$Model->alias]['beforeSave'] = $tempData; } +/** + * Restores model data to the original data. + * This solves issues with saveAssociated and validate = first. + * + * @param Model $model + * @return void + */ + public function afterValidate(Model $Model) { + $Model->data[$Model->alias] = array_merge( + $Model->data[$Model->alias], + $this->runtime[$Model->alias]['beforeSave'] + ); + return true; + } + /** * afterSave Callback * diff --git a/lib/Cake/Model/Behavior/TreeBehavior.php b/lib/Cake/Model/Behavior/TreeBehavior.php index eb316a4d7..6895fe9d0 100644 --- a/lib/Cake/Model/Behavior/TreeBehavior.php +++ b/lib/Cake/Model/Behavior/TreeBehavior.php @@ -178,7 +178,7 @@ class TreeBehavior extends ModelBehavior { extract($this->settings[$Model->alias]); $this->_addToWhitelist($Model, array($left, $right)); - if (!$Model->id) { + if (!$Model->id || !$Model->exists()) { if (array_key_exists($parent, $Model->data[$Model->alias]) && $Model->data[$Model->alias][$parent]) { $parentNode = $Model->find('first', array( 'conditions' => array($scope, $Model->escapeField() => $Model->data[$Model->alias][$parent]), diff --git a/lib/Cake/Model/ConnectionManager.php b/lib/Cake/Model/ConnectionManager.php index edbcfa5eb..4edd0ac77 100644 --- a/lib/Cake/Model/ConnectionManager.php +++ b/lib/Cake/Model/ConnectionManager.php @@ -24,7 +24,7 @@ App::uses('DataSource', 'Model/Datasource'); /** * Manages loaded instances of DataSource objects * - * Provides an interface for loading and enumerating connections defined in + * Provides an interface for loading and enumerating connections defined in * app/Config/database.php * * @package Cake.Model diff --git a/lib/Cake/Model/Datasource/DataSource.php b/lib/Cake/Model/Datasource/DataSource.php index 06f526403..af65276ce 100644 --- a/lib/Cake/Model/Datasource/DataSource.php +++ b/lib/Cake/Model/Datasource/DataSource.php @@ -420,7 +420,7 @@ class DataSource extends Object { /** * Closes a connection. Override in subclasses - * + * * @return boolean * @access public */ diff --git a/lib/Cake/Model/Datasource/Database/Sqlserver.php b/lib/Cake/Model/Datasource/Database/Sqlserver.php index 46d565400..035f120ea 100644 --- a/lib/Cake/Model/Datasource/Database/Sqlserver.php +++ b/lib/Cake/Model/Datasource/Database/Sqlserver.php @@ -637,7 +637,7 @@ class Sqlserver extends DboSource { /** * Generate a database-native column schema string * - * @param array $column An array structured like the + * @param array $column An array structured like the * following: array('name'=>'value', 'type'=>'value'[, options]), * where options can be 'default', 'length', or 'key'. * @return string diff --git a/lib/Cake/Model/Datasource/DboSource.php b/lib/Cake/Model/Datasource/DboSource.php index bae55cff9..623b7a01f 100644 --- a/lib/Cake/Model/Datasource/DboSource.php +++ b/lib/Cake/Model/Datasource/DboSource.php @@ -921,14 +921,14 @@ class DboSource extends DataSource { $this->_queriesCnt++; $this->_queriesTime += $this->took; $this->_queriesLog[] = array( - 'query' => $sql, - 'params' => $params, - 'affected' => $this->affected, - 'numRows' => $this->numRows, - 'took' => $this->took + 'query' => $sql, + 'params' => $params, + 'affected' => $this->affected, + 'numRows' => $this->numRows, + 'took' => $this->took ); if (count($this->_queriesLog) > $this->_queriesLogMax) { - array_pop($this->_queriesLog); + array_shift($this->_queriesLog); } } @@ -2490,16 +2490,16 @@ class DboSource extends DataSource { $count = count($value); if ($count === 1 && !preg_match("/\s+NOT$/", $key)) { $data = $this->_quoteFields($key) . ' = ('; - } else { - $data = $this->_quoteFields($key) . ' IN ('; - } - if ($quoteValues) { - if (is_object($model)) { - $columnType = $model->getColumnType($key); + if ($quoteValues) { + if (is_object($model)) { + $columnType = $model->getColumnType($key); + } + $data .= implode(', ', $this->value($value, $columnType)); } - $data .= implode(', ', $this->value($value, $columnType)); + $data .= ')'; + } else { + $data = $this->_parseKey($model, $key, $value); } - $data .= ')'; } else { $ret = $this->conditionKeysToString($value, $quoteValues, $model); if (count($ret) > 1) { @@ -2917,6 +2917,10 @@ class DboSource extends DataSource { } $statement->execute(); $statement->closeCursor(); + + if ($this->fullDebug) { + $this->logQuery($sql, $value); + } } return $this->commit(); } @@ -2984,7 +2988,7 @@ class DboSource extends DataSource { $tableParameters = array_merge($tableParameters, $this->buildTableParameters($col, $table)); } } - if (empty($indexes) && !empty($primary)) { + if (!isset($columns['indexes']['PRIMARY']) && !empty($primary)) { $col = array('PRIMARY' => array('column' => $primary, 'unique' => 1)); $indexes = array_merge($indexes, $this->buildIndex($col, $table)); } diff --git a/lib/Cake/Model/Model.php b/lib/Cake/Model/Model.php index b597ae297..2104739ac 100644 --- a/lib/Cake/Model/Model.php +++ b/lib/Cake/Model/Model.php @@ -558,6 +558,8 @@ class Model extends Object implements CakeEventListener { */ protected $_associations = array('belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany'); +// @codingStandardsIgnoreStart + /** * Holds model associations temporarily to allow for dynamic (un)binding. * @@ -586,6 +588,8 @@ class Model extends Object implements CakeEventListener { */ public $__backContainableAssociation = array(); +// @codingStandardsIgnoreEnd + /** * The ID of the model record that was last inserted. * @@ -1082,7 +1086,7 @@ class Model extends Object implements CakeEventListener { } /** - * Sets a custom table for your controller class. Used by your controller to select a database table. + * Sets a custom table for your model class. Used by your controller to select a database table. * * @param string $tableName Name of the custom table * @throws MissingTableException when database table $tableName is not found on data source @@ -2017,7 +2021,7 @@ class Model extends Object implements CakeEventListener { * @link http://book.cakephp.org/2.0/en/models/saving-your-data.html#model-saveassociated-array-data-null-array-options-array * @link http://book.cakephp.org/2.0/en/models/saving-your-data.html#model-saveall-array-data-null-array-options-array */ - public function saveAll($data, $options = array()) { + public function saveAll($data = array(), $options = array()) { $options = array_merge(array('validate' => 'first'), $options); if (Hash::numeric(array_keys($data))) { if ($options['validate'] === 'only') { @@ -2183,7 +2187,7 @@ class Model extends Object implements CakeEventListener { if ($options['validate'] === 'first') { $validates = $this->validateAssociated($data, $options); - if ((!$validates && $options['atomic']) || (!$options['atomic'] && in_array(false, $validates, true))) { + if ((!$validates && $options['atomic']) || (!$options['atomic'] && in_array(false, Hash::flatten($validates), true))) { return $validates; } $options['validate'] = false; @@ -2613,9 +2617,12 @@ class Model extends Object implements CakeEventListener { * * Note: find(list) + database views have issues with MySQL 5.0. Try upgrading to MySQL 5.1 if you * have issues with database views. + * + * Note: find(count) has its own return values. + * * @param string $type Type of find operation (all / first / count / neighbors / list / threaded) * @param array $query Option fields (conditions / fields / joins / limit / offset / order / page / group / callbacks) - * @return array Array of records + * @return array Array of records, or Null on failure. * @link http://book.cakephp.org/2.0/en/models/deleting-data.html#deleteall */ public function find($type = 'first', $query = array()) { @@ -2638,10 +2645,10 @@ class Model extends Object implements CakeEventListener { if ($type === 'all') { return $results; - } else { - if ($this->findMethods[$type] === true) { - return $this->{'_find' . ucfirst($type)}('after', $query, $results); - } + } + + if ($this->findMethods[$type] === true) { + return $this->{'_find' . ucfirst($type)}('after', $query, $results); } } @@ -2707,7 +2714,7 @@ class Model extends Object implements CakeEventListener { return $query; } elseif ($state === 'after') { if (empty($results[0])) { - return false; + return array(); } return $results[0]; } @@ -2749,8 +2756,8 @@ class Model extends Object implements CakeEventListener { } elseif ($state === 'after') { foreach (array(0, $this->alias) as $key) { if (isset($results[0][$key]['count'])) { - if (($count = count($results)) > 1) { - return $count; + if ($query['group']) { + return count($results); } else { return intval($results[0][$key]['count']); } diff --git a/lib/Cake/Model/Validator/CakeValidationRule.php b/lib/Cake/Model/Validator/CakeValidationRule.php index 6380376bf..3ce7c2fcd 100644 --- a/lib/Cake/Model/Validator/CakeValidationRule.php +++ b/lib/Cake/Model/Validator/CakeValidationRule.php @@ -163,9 +163,9 @@ class CakeValidationRule { */ public function checkRequired($field, &$data) { return ( - (!isset($data[$field]) && $this->isRequired() === true) || + (!array_key_exists($field, $data) && $this->isRequired() === true) || ( - isset($data[$field]) && (empty($data[$field]) && + array_key_exists($field, $data) && (empty($data[$field]) && !is_numeric($data[$field])) && $this->allowEmpty === false ) ); diff --git a/lib/Cake/Model/Validator/CakeValidationSet.php b/lib/Cake/Model/Validator/CakeValidationSet.php index 3451f8103..4ada8bd27 100644 --- a/lib/Cake/Model/Validator/CakeValidationSet.php +++ b/lib/Cake/Model/Validator/CakeValidationSet.php @@ -192,7 +192,7 @@ class CakeValidationSet implements ArrayAccess, IteratorAggregate, Countable { * @return CakeValidationSet this instance */ public function setRule($name, $rule) { - if (!$rule instanceof CakeValidationRule) { + if (!($rule instanceof CakeValidationRule)) { $rule = new CakeValidationRule($rule); } $this->_rules[$name] = $rule; @@ -236,9 +236,10 @@ class CakeValidationSet implements ArrayAccess, IteratorAggregate, Countable { */ public function setRules($rules = array(), $mergeVars = true) { if ($mergeVars === false) { - $this->_rules = $rules; - } else { - $this->_rules = array_merge($this->_rules, $rules); + $this->_rules = array(); + } + foreach ($rules as $name => $rule) { + $this->setRule($name, $rule); } return $this; } @@ -280,7 +281,7 @@ class CakeValidationSet implements ArrayAccess, IteratorAggregate, Countable { $message = __d($this->_validationDomain, $name); } } else { - $message = __d('cake_dev', 'This field cannot be left blank'); + $message = __d('cake', 'This field cannot be left blank'); } return $message; diff --git a/lib/Cake/Network/CakeRequest.php b/lib/Cake/Network/CakeRequest.php index 238793912..903fa72ca 100644 --- a/lib/Cake/Network/CakeRequest.php +++ b/lib/Cake/Network/CakeRequest.php @@ -15,8 +15,7 @@ * @since CakePHP(tm) v 2.0 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ - -App::uses('Set', 'Utility'); +App::uses('Hash', 'Utility'); /** * A class that helps wrap Request information and particulars about a single request. @@ -163,11 +162,12 @@ class CakeRequest implements ArrayAccess { protected function _processPost() { if ($_POST) { $this->data = $_POST; - } elseif ($this->is('put') || $this->is('delete')) { - $this->data = $this->_readInput(); - if (strpos(env('CONTENT_TYPE'), 'application/x-www-form-urlencoded') === 0) { - parse_str($this->data, $this->data); - } + } elseif ( + ($this->is('put') || $this->is('delete')) && + strpos(env('CONTENT_TYPE'), 'application/x-www-form-urlencoded') === 0 + ) { + $data = $this->_readInput(); + parse_str($data, $this->data); } if (ini_get('magic_quotes_gpc') === '1') { $this->data = stripslashes_deep($this->data); @@ -229,8 +229,10 @@ class CakeRequest implements ArrayAccess { protected function _url() { if (!empty($_SERVER['PATH_INFO'])) { return $_SERVER['PATH_INFO']; - } elseif (isset($_SERVER['REQUEST_URI'])) { + } elseif (isset($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'], '://') === false) { $uri = $_SERVER['REQUEST_URI']; + } elseif (isset($_SERVER['REQUEST_URI'])) { + $uri = substr($_SERVER['REQUEST_URI'], strlen(FULL_BASE_URL)); } elseif (isset($_SERVER['PHP_SELF']) && isset($_SERVER['SCRIPT_NAME'])) { $uri = str_replace($_SERVER['SCRIPT_NAME'], '', $_SERVER['PHP_SELF']); } elseif (isset($_SERVER['HTTP_X_REWRITE_URL'])) { @@ -319,7 +321,7 @@ class CakeRequest implements ArrayAccess { protected function _processFiles() { if (isset($_FILES) && is_array($_FILES)) { foreach ($_FILES as $name => $data) { - if ($name != 'data') { + if ($name !== 'data') { $this->params['form'][$name] = $data; } } @@ -351,7 +353,7 @@ class CakeRequest implements ArrayAccess { $this->_processFileData($newPath, $fields, $field); } else { $newPath .= '.' . $field; - $this->data = Set::insert($this->data, $newPath, $fields); + $this->data = Hash::insert($this->data, $newPath, $fields); } } } diff --git a/lib/Cake/Network/Email/CakeEmail.php b/lib/Cake/Network/Email/CakeEmail.php index b812dac97..9bf4d434e 100644 --- a/lib/Cake/Network/Email/CakeEmail.php +++ b/lib/Cake/Network/Email/CakeEmail.php @@ -1035,7 +1035,7 @@ class CakeEmail { /** * Send an email using the specified content, template and layout - * + * * @param string|array $content String with message or array with messages * @return array * @throws SocketException @@ -1337,7 +1337,7 @@ class CakeEmail { /** * Attach non-embedded files by adding file contents inside boundaries. * - * @param string $boundary Boundary to use. If null, will default to $this->_boundary + * @param string $boundary Boundary to use. If null, will default to $this->_boundary * @return array An array of lines to add to the message */ protected function _attachFiles($boundary = null) { @@ -1380,7 +1380,7 @@ class CakeEmail { /** * Attach inline/embedded files to the message. * - * @param string $boundary Boundary to use. If null, will default to $this->_boundary + * @param string $boundary Boundary to use. If null, will default to $this->_boundary * @return array An array of lines to add to the message */ protected function _attachInlineFiles($boundary = null) { diff --git a/lib/Cake/Network/Http/HttpSocket.php b/lib/Cake/Network/Http/HttpSocket.php index 502505676..bda8ec4c7 100644 --- a/lib/Cake/Network/Http/HttpSocket.php +++ b/lib/Cake/Network/Http/HttpSocket.php @@ -403,7 +403,7 @@ class HttpSocket extends CakeSocket { } if ($this->request['redirect'] && $this->response->isRedirect()) { - $request['uri'] = $this->response->getHeader('Location'); + $request['uri'] = trim(urldecode($this->response->getHeader('Location')), '='); $request['redirect'] = is_int($this->request['redirect']) ? $this->request['redirect'] - 1 : $this->request['redirect']; $this->response = $this->request($request); } diff --git a/lib/Cake/Routing/Router.php b/lib/Cake/Routing/Router.php index 2c56c5290..2a02570cd 100644 --- a/lib/Cake/Routing/Router.php +++ b/lib/Cake/Routing/Router.php @@ -633,7 +633,7 @@ class Router { * @return array Parameter information */ public static function getParams($current = false) { - if ($current) { + if ($current && self::$_requests) { return self::$_requests[count(self::$_requests) - 1]->params; } if (isset(self::$_requests[0])) { diff --git a/lib/Cake/Test/Case/BasicsTest.php b/lib/Cake/Test/Case/BasicsTest.php index 0c12fed6f..0998dfa77 100644 --- a/lib/Cake/Test/Case/BasicsTest.php +++ b/lib/Cake/Test/Case/BasicsTest.php @@ -67,7 +67,7 @@ class BasicsTest extends CakeTestCase { $one = array('minYear' => null, 'maxYear' => null, 'separator' => '-', 'interval' => 1, 'monthNames' => true); $two = array('minYear' => null, 'maxYear' => null, 'separator' => '-', 'interval' => 1, 'monthNames' => true); $result = array_diff_key($one, $two); - $this->assertEquals(array(), $result); + $this->assertSame(array(), $result); } /** diff --git a/lib/Cake/Test/Case/Cache/Engine/FileEngineTest.php b/lib/Cake/Test/Case/Cache/Engine/FileEngineTest.php index a091fbd6e..6f506d845 100644 --- a/lib/Cake/Test/Case/Cache/Engine/FileEngineTest.php +++ b/lib/Cake/Test/Case/Cache/Engine/FileEngineTest.php @@ -102,7 +102,7 @@ class FileEngineTest extends CakeTestCase { /** * Test read/write on the same cache key. Ensures file handles are re-wound. - * + * * @return void */ public function testConsecutiveReadWrite() { diff --git a/lib/Cake/Test/Case/Cache/Engine/MemcacheEngineTest.php b/lib/Cake/Test/Case/Cache/Engine/MemcacheEngineTest.php index a1c2abd5b..54c225c72 100644 --- a/lib/Cake/Test/Case/Cache/Engine/MemcacheEngineTest.php +++ b/lib/Cake/Test/Case/Cache/Engine/MemcacheEngineTest.php @@ -121,7 +121,6 @@ class MemcacheEngineTest extends CakeTestCase { $Memcache = new MemcacheEngine(); $Memcache->init(array('engine' => 'Memcache', 'servers' => $servers)); - $servers = array_keys($Memcache->__Memcache->getExtendedStats()); $settings = $Memcache->settings(); $this->assertEquals($settings['servers'], $servers); Cache::drop('dual_server'); @@ -230,12 +229,11 @@ class MemcacheEngineTest extends CakeTestCase { $result = Cache::write('other_test', $data, 'memcache'); $this->assertTrue($result); - sleep(2); + sleep(3); $result = Cache::read('other_test', 'memcache'); $this->assertFalse($result); Cache::config('memcache', array('duration' => '+1 second')); - sleep(2); $result = Cache::read('other_test', 'memcache'); $this->assertFalse($result); diff --git a/lib/Cake/Test/Case/Console/Command/AclShellTest.php b/lib/Cake/Test/Case/Console/Command/AclShellTest.php index 7dfbbc061..cf98cabf5 100644 --- a/lib/Cake/Test/Case/Console/Command/AclShellTest.php +++ b/lib/Cake/Test/Case/Console/Command/AclShellTest.php @@ -177,7 +177,7 @@ class AclShellTest extends CakeTestCase { $Aro = ClassRegistry::init('Aro'); $result = $Aro->findById(3); - $this->assertFalse($result); + $this->assertSame(array(), $result); } /** diff --git a/lib/Cake/Test/Case/Console/Command/Task/ControllerTaskTest.php b/lib/Cake/Test/Case/Console/Command/Task/ControllerTaskTest.php index a17d2bb9d..4d11cbe60 100644 --- a/lib/Cake/Test/Case/Console/Command/Task/ControllerTaskTest.php +++ b/lib/Cake/Test/Case/Console/Command/Task/ControllerTaskTest.php @@ -181,7 +181,7 @@ class ControllerTaskTest extends CakeTestCase { public function testDoHelpersNo() { $this->Task->expects($this->any())->method('in')->will($this->returnValue('n')); $result = $this->Task->doHelpers(); - $this->assertEquals(array(), $result); + $this->assertSame(array(), $result); } /** @@ -218,7 +218,7 @@ class ControllerTaskTest extends CakeTestCase { public function testDoComponentsNo() { $this->Task->expects($this->any())->method('in')->will($this->returnValue('n')); $result = $this->Task->doComponents(); - $this->assertEquals(array(), $result); + $this->assertSame(array(), $result); } /** diff --git a/lib/Cake/Test/Case/Console/Command/TestShellTest.php b/lib/Cake/Test/Case/Console/Command/TestShellTest.php index 5d08c584d..ddae489e2 100644 --- a/lib/Cake/Test/Case/Console/Command/TestShellTest.php +++ b/lib/Cake/Test/Case/Console/Command/TestShellTest.php @@ -64,7 +64,7 @@ class TestShellTest extends CakeTestCase { /** * testMapCoreFileToCategory - * + * * @return void */ public function testMapCoreFileToCategory() { @@ -84,7 +84,7 @@ class TestShellTest extends CakeTestCase { * testMapCoreFileToCase * * basics.php is a slightly special case - it's the only file in the core with a test that isn't Capitalized - * + * * @return void */ public function testMapCoreFileToCase() { @@ -102,7 +102,7 @@ class TestShellTest extends CakeTestCase { /** * testMapAppFileToCategory - * + * * @return void */ public function testMapAppFileToCategory() { @@ -132,7 +132,7 @@ class TestShellTest extends CakeTestCase { /** * testMapPluginFileToCategory - * + * * @return void */ public function testMapPluginFileToCategory() { @@ -162,7 +162,7 @@ class TestShellTest extends CakeTestCase { /** * testMapCoreTestToCategory - * + * * @return void */ public function testMapCoreTestToCategory() { @@ -182,7 +182,7 @@ class TestShellTest extends CakeTestCase { * testMapCoreTestToCase * * basics.php is a slightly special case - it's the only file in the core with a test that isn't Capitalized - * + * * @return void */ public function testMapCoreTestToCase() { @@ -200,7 +200,7 @@ class TestShellTest extends CakeTestCase { /** * testMapAppTestToCategory - * + * * @return void */ public function testMapAppTestToCategory() { @@ -230,7 +230,7 @@ class TestShellTest extends CakeTestCase { /** * testMapPluginTestToCategory - * + * * @return void */ public function testMapPluginTestToCategory() { diff --git a/lib/Cake/Test/Case/Controller/Component/Acl/DbAclTest.php b/lib/Cake/Test/Case/Controller/Component/Acl/DbAclTest.php index bfc33f68a..c0964ccb0 100644 --- a/lib/Cake/Test/Case/Controller/Component/Acl/DbAclTest.php +++ b/lib/Cake/Test/Case/Controller/Component/Acl/DbAclTest.php @@ -483,14 +483,14 @@ class DbAclTest extends CakeTestCase { /** * debug function - to help editing/creating test cases for the ACL component * - * To check the overall ACL status at any time call $this->__debug(); + * 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) { + protected function _debug($printTreesToo = false) { $this->Acl->Aro->displayField = 'alias'; $this->Acl->Aco->displayField = 'alias'; $aros = $this->Acl->Aro->find('list', array('order' => 'lft')); @@ -518,10 +518,10 @@ class DbAclTest extends CakeTestCase { } foreach ($permissions as $key => $values) { array_unshift($values, $key); - $values = array_map(array(&$this, '__pad'), $values); + $values = array_map(array(&$this, '_pad'), $values); $permissions[$key] = implode (' ', $values); } - $permisssions = array_map(array(&$this, '__pad'), $permissions); + $permisssions = array_map(array(&$this, '_pad'), $permissions); array_unshift($permissions, 'Current Permissions :'); if ($printTreesToo) { debug(array('aros' => $this->Acl->Aro->generateTreeList(), 'acos' => $this->Acl->Aco->generateTreeList())); @@ -537,7 +537,7 @@ class DbAclTest extends CakeTestCase { * @param integer $len * @return void */ - protected function __pad($string = '', $len = 14) { + protected function _pad($string = '', $len = 14) { return str_pad($string, $len); } } diff --git a/lib/Cake/Test/Case/Controller/Component/CookieComponentTest.php b/lib/Cake/Test/Case/Controller/Component/CookieComponentTest.php index 380c29099..7c4be8972 100644 --- a/lib/Cake/Test/Case/Controller/Component/CookieComponentTest.php +++ b/lib/Cake/Test/Case/Controller/Component/CookieComponentTest.php @@ -412,11 +412,11 @@ class CookieComponentTest extends CakeTestCase { $this->assertNull($data); $_COOKIE['CakeTestCookie'] = array( - 'Encrytped_array' => $this->__encrypt(array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' => 'CakePHP Rocks!')), + 'Encrytped_array' => $this->_encrypt(array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' => 'CakePHP Rocks!')), 'Encrytped_multi_cookies' => array( - 'name' => $this->__encrypt('CakePHP'), - 'version' => $this->__encrypt('1.2.0.x'), - 'tag' => $this->__encrypt('CakePHP Rocks!')), + 'name' => $this->_encrypt('CakePHP'), + 'version' => $this->_encrypt('1.2.0.x'), + 'tag' => $this->_encrypt('CakePHP Rocks!')), 'Plain_array' => '{"name":"CakePHP","version":"1.2.0.x","tag":"CakePHP Rocks!"}', 'Plain_multi_cookies' => array( 'name' => 'CakePHP', @@ -467,11 +467,11 @@ class CookieComponentTest extends CakeTestCase { $this->assertEquals($expected, $data); $_COOKIE['CakeTestCookie'] = array( - 'Encrytped_array' => $this->__encrypt(array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' => 'CakePHP Rocks!')), + 'Encrytped_array' => $this->_encrypt(array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' => 'CakePHP Rocks!')), 'Encrytped_multi_cookies' => array( - 'name' => $this->__encrypt('CakePHP'), - 'version' => $this->__encrypt('1.2.0.x'), - 'tag' => $this->__encrypt('CakePHP Rocks!')), + 'name' => $this->_encrypt('CakePHP'), + 'version' => $this->_encrypt('1.2.0.x'), + 'tag' => $this->_encrypt('CakePHP Rocks!')), 'Plain_array' => '{"name":"CakePHP","version":"1.2.0.x","tag":"CakePHP Rocks!"}', 'Plain_multi_cookies' => array( 'name' => 'CakePHP', @@ -594,7 +594,7 @@ class CookieComponentTest extends CakeTestCase { * @param array|string $value * @return string */ - protected function __encrypt($value) { + protected function _encrypt($value) { if (is_array($value)) { $value = $this->_implode($value); } diff --git a/lib/Cake/Test/Case/Core/AppTest.php b/lib/Cake/Test/Case/Core/AppTest.php index 3b6cef55e..0c66766cd 100644 --- a/lib/Cake/Test/Case/Core/AppTest.php +++ b/lib/Cake/Test/Case/Core/AppTest.php @@ -347,7 +347,7 @@ class AppTest extends CakeTestCase { $this->assertEquals($expected, $result); $result = App::objects('NonExistingType'); - $this->assertEquals(array(), $result); + $this->assertSame(array(), $result); App::build(array( 'plugins' => array( @@ -414,9 +414,9 @@ class AppTest extends CakeTestCase { $this->assertTrue(in_array('OtherComponent', $result)); $result = App::objects('TestPluginTwo.behavior'); - $this->assertEquals(array(), $result); + $this->assertSame(array(), $result); $result = App::objects('TestPluginTwo.Model/Behavior'); - $this->assertEquals(array(), $result); + $this->assertSame(array(), $result); $result = App::objects('model', null, false); $this->assertTrue(in_array('Comment', $result)); diff --git a/lib/Cake/Test/Case/Core/ObjectTest.php b/lib/Cake/Test/Case/Core/ObjectTest.php index 222a231a7..5738e201c 100644 --- a/lib/Cake/Test/Case/Core/ObjectTest.php +++ b/lib/Cake/Test/Case/Core/ObjectTest.php @@ -619,6 +619,24 @@ class ObjectTest extends CakeTestCase { $this->assertEquals($expected, $result['named']); } +/** + * Test that requestAction handles get parameters correctly. + * + * @return void + */ + public function testRequestActionGetParameters() { + $result = $this->object->requestAction( + '/request_action/params_pass?get=value&limit=5' + ); + $this->assertEquals('value', $result->query['get']); + + $result = $this->object->requestAction( + array('controller' => 'request_action', 'action' => 'params_pass'), + array('url' => array('get' => 'value', 'limit' => 5)) + ); + $this->assertEquals('value', $result->query['get']); + } + /** * test that requestAction does not fish data out of the POST * superglobal. @@ -632,7 +650,6 @@ class ObjectTest extends CakeTestCase { 'item' => 'value' )); $result = $this->object->requestAction(array('controller' => 'request_action', 'action' => 'post_pass')); - $expected = null; $this->assertEmpty($result); $result = $this->object->requestAction( diff --git a/lib/Cake/Test/Case/Error/ExceptionRendererTest.php b/lib/Cake/Test/Case/Error/ExceptionRendererTest.php index a5704433b..d11c66413 100644 --- a/lib/Cake/Test/Case/Error/ExceptionRendererTest.php +++ b/lib/Cake/Test/Case/Error/ExceptionRendererTest.php @@ -19,7 +19,6 @@ App::uses('ExceptionRenderer', 'Error'); App::uses('Controller', 'Controller'); -App::uses('AppController', 'Controller'); App::uses('Component', 'Controller'); App::uses('Router', 'Routing'); diff --git a/lib/Cake/Test/Case/Event/CakeEventManagerTest.php b/lib/Cake/Test/Case/Event/CakeEventManagerTest.php index 04a358ab4..9689b4d6f 100644 --- a/lib/Cake/Test/Case/Event/CakeEventManagerTest.php +++ b/lib/Cake/Test/Case/Event/CakeEventManagerTest.php @@ -53,7 +53,7 @@ class CakeEventTestListener { /** * Auxiliary function to help in stopPropagation testing * - * @param CakeEvent $event + * @param CakeEvent $event * @return void */ public function stopListener($event) { @@ -234,6 +234,10 @@ class CakeEventManagerTest extends CakeTestCase { * @return void */ public function testDispatchReturnValue() { + $this->skipIf( + version_compare(PHPUnit_Runner_Version::id(), '3.7', '<'), + 'These tests fail in PHPUnit 3.6' + ); $manager = new CakeEventManager; $listener = $this->getMock('CakeEventTestListener'); $anotherListener = $this->getMock('CakeEventTestListener'); @@ -241,11 +245,12 @@ class CakeEventManagerTest extends CakeTestCase { $manager->attach(array($anotherListener, 'listenerFunction'), 'fake.event'); $event = new CakeEvent('fake.event'); - $firstStep = clone $event; $listener->expects($this->at(0))->method('listenerFunction') - ->with($firstStep) + ->with($event) ->will($this->returnValue('something special')); - $anotherListener->expects($this->at(0))->method('listenerFunction')->with($event); + $anotherListener->expects($this->at(0)) + ->method('listenerFunction') + ->with($event); $manager->dispatch($event); $this->assertEquals('something special', $event->result); } @@ -256,6 +261,11 @@ class CakeEventManagerTest extends CakeTestCase { * @return void */ public function testDispatchFalseStopsEvent() { + $this->skipIf( + version_compare(PHPUnit_Runner_Version::id(), '3.7', '<'), + 'These tests fail in PHPUnit 3.6' + ); + $manager = new CakeEventManager; $listener = $this->getMock('CakeEventTestListener'); $anotherListener = $this->getMock('CakeEventTestListener'); @@ -263,11 +273,11 @@ class CakeEventManagerTest extends CakeTestCase { $manager->attach(array($anotherListener, 'listenerFunction'), 'fake.event'); $event = new CakeEvent('fake.event'); - $originalEvent = clone $event; $listener->expects($this->at(0))->method('listenerFunction') - ->with($originalEvent) + ->with($event) ->will($this->returnValue(false)); - $anotherListener->expects($this->never())->method('listenerFunction'); + $anotherListener->expects($this->never()) + ->method('listenerFunction'); $manager->dispatch($event); $this->assertTrue($event->isStopped()); } diff --git a/lib/Cake/Test/Case/Log/CakeLogTest.php b/lib/Cake/Test/Case/Log/CakeLogTest.php index 39f715eba..1226dde7e 100644 --- a/lib/Cake/Test/Case/Log/CakeLogTest.php +++ b/lib/Cake/Test/Case/Log/CakeLogTest.php @@ -175,7 +175,7 @@ class CakeLogTest extends CakeTestCase { CakeLog::drop('file'); $result = CakeLog::configured(); - $this->assertEquals(array(), $result); + $this->assertSame(array(), $result); } /** @@ -331,21 +331,22 @@ class CakeLogTest extends CakeTestCase { /** * test backward compatible scoped logging + * + * @return void */ public function testScopedLoggingBC() { - $this->_deleteLogs(); - $this->_resetLogConfig(); + CakeLog::config('shops', array( 'engine' => 'FileLog', 'types' => array('info', 'notice', 'warning'), 'scopes' => array('transactions', 'orders'), 'file' => 'shops', - )); + )); + $this->_deleteLogs(); CakeLog::write('info', 'info message'); $this->assertFalse(file_exists(LOGS . 'error.log')); - $this->assertTrue(file_exists(LOGS . 'shops.log')); $this->assertTrue(file_exists(LOGS . 'debug.log')); $this->_deleteLogs(); @@ -375,7 +376,6 @@ class CakeLogTest extends CakeTestCase { CakeLog::write('warning', 'warning message'); $this->assertTrue(file_exists(LOGS . 'error.log')); - $this->assertTrue(file_exists(LOGS . 'shops.log')); $this->assertFalse(file_exists(LOGS . 'debug.log')); $this->_deleteLogs(); @@ -383,29 +383,47 @@ class CakeLogTest extends CakeTestCase { CakeLog::drop('shops'); } + public function testScopedLoggingExclusive() { + $this->_deleteLogs(); + + CakeLog::config('shops', array( + 'engine' => 'FileLog', + 'types' => array('info', 'notice', 'warning'), + 'scopes' => array('transactions', 'orders'), + 'file' => 'shops.log', + )); + CakeLog::config('eggs', array( + 'engine' => 'FileLog', + 'types' => array('info', 'notice', 'warning'), + 'scopes' => array('eggs'), + 'file' => 'eggs.log', + )); + + CakeLog::write('info', 'transactions message', 'transactions'); + $this->assertFalse(file_exists(LOGS . 'eggs.log')); + $this->assertTrue(file_exists(LOGS . 'shops.log')); + + $this->_deleteLogs(); + + CakeLog::write('info', 'eggs message', 'eggs'); + $this->assertTrue(file_exists(LOGS . 'eggs.log')); + $this->assertFalse(file_exists(LOGS . 'shops.log')); + } + /** * test scoped logging * * @return void */ public function testScopedLogging() { - if (file_exists(LOGS . 'shops.log')) { - unlink(LOGS . 'shops.log'); - } - if (file_exists(LOGS . 'error.log')) { - unlink(LOGS . 'error.log'); - } - if (file_exists(LOGS . 'debug.log')) { - unlink(LOGS . 'debug.log'); - } - $this->_resetLogConfig(); + $this->_deleteLogs(); CakeLog::config('shops', array( 'engine' => 'FileLog', 'types' => array('info', 'notice', 'warning'), 'scopes' => array('transactions', 'orders'), - 'file' => 'shops', - )); + 'file' => 'shops.log', + )); CakeLog::write('info', 'info message', 'transactions'); $this->assertFalse(file_exists(LOGS . 'error.log')); diff --git a/lib/Cake/Test/Case/Model/Behavior/ContainableBehaviorTest.php b/lib/Cake/Test/Case/Model/Behavior/ContainableBehaviorTest.php index 8345c87d6..d84f07e67 100644 --- a/lib/Cake/Test/Case/Model/Behavior/ContainableBehaviorTest.php +++ b/lib/Cake/Test/Case/Model/Behavior/ContainableBehaviorTest.php @@ -261,6 +261,19 @@ class ContainableBehaviorTest extends CakeTestCase { $this->assertFalse(Set::matches('/Comment/User', $r)); } +/** + * Test that mixing contain() and the contain find option. + * + * @return void + */ + public function testContainAndContainOption() { + $this->Article->contain(); + $r = $this->Article->find('all', array( + 'contain' => array('Comment') + )); + $this->assertTrue(isset($r[0]['Comment']), 'No comment returned'); + } + /** * testFindEmbeddedNoBindings method * @@ -2980,7 +2993,8 @@ class ContainableBehaviorTest extends CakeTestCase { 'User' => array( 'fields' => array('user') ) - ) + ), + 'order' => 'Article.id ASC', )); $this->assertTrue(isset($result[0]['Article']['title']), 'title missing %s'); $this->assertTrue(isset($result[0]['Article']['body']), 'body missing %s'); @@ -3003,7 +3017,10 @@ class ContainableBehaviorTest extends CakeTestCase { 'conditions' => array('created >=' => '2007-03-18 12:24') ) )); - $result = $this->Article->find('all', array('fields' => array('title'), 'order' => array('Article.id' => 'ASC'))); + $result = $this->Article->find('all', array( + 'fields' => array('title'), + 'order' => array('Article.id' => 'ASC') + )); $expected = array( array( 'Article' => array('id' => 1, 'title' => 'First Article'), diff --git a/lib/Cake/Test/Case/Model/Behavior/TranslateBehaviorTest.php b/lib/Cake/Test/Case/Model/Behavior/TranslateBehaviorTest.php index 9a7ab4342..50d897d60 100644 --- a/lib/Cake/Test/Case/Model/Behavior/TranslateBehaviorTest.php +++ b/lib/Cake/Test/Case/Model/Behavior/TranslateBehaviorTest.php @@ -422,7 +422,7 @@ class TranslateBehaviorTest extends CakeTestCase { $TestModel = new TranslatedItem(); $TestModel->locale = 'rus'; $result = $TestModel->read(null, 1); - $this->assertFalse($result); + $this->assertSame(array(), $result); $TestModel->locale = array('rus'); $result = $TestModel->read(null, 1); @@ -460,10 +460,10 @@ class TranslateBehaviorTest extends CakeTestCase { Configure::write('debug', 0); $result = $TestModel->find('list', array('recursive' => 1, 'callbacks' => false)); - $this->assertEquals(array(), $result); + $this->assertSame(array(), $result); $result = $TestModel->find('list', array('recursive' => 1, 'callbacks' => 'after')); - $this->assertEquals(array(), $result); + $this->assertSame(array(), $result); Configure::write('debug', $debug); } @@ -530,6 +530,38 @@ class TranslateBehaviorTest extends CakeTestCase { $this->assertEquals($expected, $result); } +/** + * testSaveAssociatedCreate method + * + * @return void + */ + public function testSaveAssociatedMultipleLocale() { + $this->loadFixtures('Translate', 'TranslatedItem'); + + $TestModel = new TranslatedItem(); + $data = array( + 'slug' => 'fourth_translated', + 'title' => array( + 'eng' => 'Title #4', + 'spa' => 'Leyenda #4', + ), + 'content' => array( + 'eng' => 'Content #4', + 'spa' => 'Contenido #4', + ), + 'translated_article_id' => 1, + ); + $TestModel->create(); + $TestModel->saveAssociated($data); + + $translations = array('title' => 'Title', 'content' => 'Content'); + $TestModel->bindTranslation($translations, false); + $TestModel->locale = array('eng', 'spa'); + $result = $TestModel->read(); + $this->assertCount(2, $result['Title']); + $this->assertCount(2, $result['Content']); + } + /** * Test that saving only some of the translated fields allows the record to be found again. * diff --git a/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorNumberTest.php b/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorNumberTest.php index d93c6334e..adcbf4c58 100644 --- a/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorNumberTest.php +++ b/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorNumberTest.php @@ -354,8 +354,6 @@ class TreeBehaviorNumberTest extends CakeTestCase { $expected = array_merge(array($modelClass => array('name' => 'testAddMiddle', $parentField => '2')), $result); $this->assertSame($expected, $result); - $laterCount = $this->Tree->find('count'); - $laterCount = $this->Tree->find('count'); $this->assertEquals($initialCount + 1, $laterCount); @@ -369,6 +367,36 @@ class TreeBehaviorNumberTest extends CakeTestCase { $this->assertSame($validTree, true); } +/** + * testAddWithPreSpecifiedId method + * + * @return void + */ + public function testAddWithPreSpecifiedId() { + extract($this->settings); + $this->Tree = new $modelClass(); + $this->Tree->initialize(2, 2); + + $data = $this->Tree->find('first', array( + 'fields' => array('id'), + 'conditions' => array($modelClass . '.name' => '1.1') + )); + + $this->Tree->create(); + $result = $this->Tree->save(array($modelClass => array( + 'id' => 100, + 'name' => 'testAddMiddle', + $parentField => $data[$modelClass]['id']) + )); + $expected = array_merge( + array($modelClass => array('id' => 100, 'name' => 'testAddMiddle', $parentField => '2')), + $result + ); + $this->assertSame($expected, $result); + + $this->assertTrue($this->Tree->verify()); + } + /** * testAddInvalid method * diff --git a/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorScopedTest.php b/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorScopedTest.php index b9e829758..66adac3e5 100644 --- a/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorScopedTest.php +++ b/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorScopedTest.php @@ -169,12 +169,13 @@ class TreeBehaviorScopedTest extends CakeTestCase { public function testTranslatingTree() { $this->Tree = new FlagTree(); $this->Tree->cacheQueries = false; - $this->Tree->Behaviors->attach('Translate', array('name')); + $this->Tree->Behaviors->attach('Translate', array('title')); //Save $this->Tree->locale = 'eng'; $data = array('FlagTree' => array( - 'name' => 'name #1', + 'title' => 'name #1', + 'name' => 'test', 'locale' => 'eng', 'parent_id' => null, )); @@ -182,7 +183,8 @@ class TreeBehaviorScopedTest extends CakeTestCase { $result = $this->Tree->find('all'); $expected = array(array('FlagTree' => array( 'id' => 1, - 'name' => 'name #1', + 'title' => 'name #1', + 'name' => 'test', 'parent_id' => null, 'lft' => 1, 'rght' => 2, @@ -191,15 +193,16 @@ class TreeBehaviorScopedTest extends CakeTestCase { ))); $this->assertEquals($expected, $result); - //update existing record, same locale + // update existing record, same locale $this->Tree->create(); - $data['FlagTree']['name'] = 'Named 2'; + $data['FlagTree']['title'] = 'Named 2'; $this->Tree->id = 1; $this->Tree->save($data); $result = $this->Tree->find('all'); $expected = array(array('FlagTree' => array( 'id' => 1, - 'name' => 'Named 2', + 'title' => 'Named 2', + 'name' => 'test', 'parent_id' => null, 'lft' => 1, 'rght' => 2, @@ -208,51 +211,67 @@ class TreeBehaviorScopedTest extends CakeTestCase { ))); $this->assertEquals($expected, $result); - //update different locale, same record + // update different locale, same record $this->Tree->create(); $this->Tree->locale = 'deu'; $this->Tree->id = 1; $data = array('FlagTree' => array( 'id' => 1, 'parent_id' => null, - 'name' => 'namen #1', + 'title' => 'namen #1', + 'name' => 'test', 'locale' => 'deu', )); $this->Tree->save($data); $this->Tree->locale = 'deu'; $result = $this->Tree->find('all'); - $expected = array(array('FlagTree' => array( - 'id' => 1, - 'name' => 'namen #1', - 'parent_id' => null, - 'lft' => 1, - 'rght' => 2, - 'flag' => 0, - 'locale' => 'deu', - ))); + $expected = array( + array( + 'FlagTree' => array( + 'id' => 1, + 'title' => 'namen #1', + 'name' => 'test', + 'parent_id' => null, + 'lft' => 1, + 'rght' => 2, + 'flag' => 0, + 'locale' => 'deu', + ) + ) + ); $this->assertEquals($expected, $result); - //Save with bindTranslation + // Save with bindTranslation $this->Tree->locale = 'eng'; $data = array( - 'name' => array('eng' => 'New title', 'spa' => 'Nuevo leyenda'), + 'title' => array('eng' => 'New title', 'spa' => 'Nuevo leyenda'), + 'name' => 'test', 'parent_id' => null ); $this->Tree->create($data); $this->Tree->save(); $this->Tree->unbindTranslation(); - $translations = array('name' => 'Name'); + $translations = array('title' => 'Title'); $this->Tree->bindTranslation($translations, false); $this->Tree->locale = array('eng', 'spa'); $result = $this->Tree->read(); $expected = array( - 'FlagTree' => array('id' => 2, 'parent_id' => null, 'locale' => 'eng', 'name' => 'New title', 'flag' => 0, 'lft' => 3, 'rght' => 4), - 'Name' => array( - array('id' => 21, 'locale' => 'eng', 'model' => 'FlagTree', 'foreign_key' => 2, 'field' => 'name', 'content' => 'New title'), - array('id' => 22, 'locale' => 'spa', 'model' => 'FlagTree', 'foreign_key' => 2, 'field' => 'name', 'content' => 'Nuevo leyenda') + 'FlagTree' => array( + 'id' => 2, + 'parent_id' => null, + 'locale' => 'eng', + 'name' => 'test', + 'title' => 'New title', + 'flag' => 0, + 'lft' => 3, + 'rght' => 4 + ), + 'Title' => array( + array('id' => 21, 'locale' => 'eng', 'model' => 'FlagTree', 'foreign_key' => 2, 'field' => 'title', 'content' => 'New title'), + array('id' => 22, 'locale' => 'spa', 'model' => 'FlagTree', 'foreign_key' => 2, 'field' => 'title', 'content' => 'Nuevo leyenda') ), ); $this->assertEquals($expected, $result); diff --git a/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorUuidTest.php b/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorUuidTest.php index a69445ef9..bd3590b3c 100644 --- a/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorUuidTest.php +++ b/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorUuidTest.php @@ -21,6 +21,7 @@ App::uses('Model', 'Model'); App::uses('AppModel', 'Model'); +App::uses('String', 'Utility'); require_once dirname(dirname(__FILE__)) . DS . 'models.php'; /** @@ -56,6 +57,37 @@ class TreeBehaviorUuidTest extends CakeTestCase { */ public $fixtures = array('core.uuid_tree'); +/** + * testAddWithPreSpecifiedId method + * + * @return void + */ + public function testAddWithPreSpecifiedId() { + extract($this->settings); + $this->Tree = new $modelClass(); + $this->Tree->initialize(2, 2); + + $data = $this->Tree->find('first', array( + 'fields' => array('id'), + 'conditions' => array($modelClass . '.name' => '1.1') + )); + + $id = String::uuid(); + $this->Tree->create(); + $result = $this->Tree->save(array($modelClass => array( + 'id' => $id, + 'name' => 'testAddMiddle', + $parentField => $data[$modelClass]['id']) + )); + $expected = array_merge( + array($modelClass => array('id' => $id, 'name' => 'testAddMiddle', $parentField => '2')), + $result + ); + $this->assertSame($expected, $result); + + $this->assertTrue($this->Tree->verify()); + } + /** * testMovePromote method * diff --git a/lib/Cake/Test/Case/Model/BehaviorCollectionTest.php b/lib/Cake/Test/Case/Model/BehaviorCollectionTest.php index 19497f7a6..21104eda5 100644 --- a/lib/Cake/Test/Case/Model/BehaviorCollectionTest.php +++ b/lib/Cake/Test/Case/Model/BehaviorCollectionTest.php @@ -786,21 +786,22 @@ class BehaviorCollectionTest extends CakeTestCase { public function testBehaviorBelongsToFindCallbacks() { $this->skipIf($this->db instanceof Sqlserver, 'This test is not compatible with SQL Server.'); + $conditions = array('order' => 'Apple.id ASC'); $Apple = new Apple(); $Apple->unbindModel(array('hasMany' => array('Child'), 'hasOne' => array('Sample')), false); - $expected = $Apple->find('all'); + $expected = $Apple->find('all', $conditions); $Apple->unbindModel(array('belongsTo' => array('Parent'))); - $wellBehaved = $Apple->find('all'); + $wellBehaved = $Apple->find('all', $conditions); $Apple->Parent->Behaviors->attach('Test'); $Apple->unbindModel(array('belongsTo' => array('Parent'))); - $this->assertSame($Apple->find('all'), $wellBehaved); + $this->assertSame($Apple->find('all', $conditions), $wellBehaved); $Apple->Parent->Behaviors->attach('Test', array('before' => 'off')); - $this->assertSame($expected, $Apple->find('all')); + $this->assertSame($expected, $Apple->find('all', $conditions)); $Apple->Parent->Behaviors->attach('Test', array('before' => 'test')); - $this->assertSame($expected, $Apple->find('all')); + $this->assertSame($expected, $Apple->find('all', $conditions)); $Apple->Parent->Behaviors->attach('Test', array('before' => 'modify')); $expected2 = array( @@ -816,22 +817,23 @@ class BehaviorCollectionTest extends CakeTestCase { ); $result2 = $Apple->find('all', array( 'fields' => array('Apple.id', 'Parent.id', 'Parent.name', 'Parent.mytime'), - 'conditions' => array('Apple.id <' => '4') + 'conditions' => array('Apple.id <' => '4'), + 'order' => 'Apple.id ASC', )); $this->assertEquals($expected2, $result2); $Apple->Parent->Behaviors->disable('Test'); - $result = $Apple->find('all'); + $result = $Apple->find('all', $conditions); $this->assertEquals($expected, $result); $Apple->Parent->Behaviors->attach('Test', array('after' => 'off')); - $this->assertEquals($expected, $Apple->find('all')); + $this->assertEquals($expected, $Apple->find('all', $conditions)); $Apple->Parent->Behaviors->attach('Test', array('after' => 'test')); - $this->assertEquals($expected, $Apple->find('all')); + $this->assertEquals($expected, $Apple->find('all', $conditions)); $Apple->Parent->Behaviors->attach('Test', array('after' => 'test2')); - $this->assertEquals($expected, $Apple->find('all')); + $this->assertEquals($expected, $Apple->find('all', $conditions)); } /** diff --git a/lib/Cake/Test/Case/Model/Datasource/DataSourceTest.php b/lib/Cake/Test/Case/Model/Datasource/DataSourceTest.php index 3bb9bd0d7..a0de0aba2 100644 --- a/lib/Cake/Test/Case/Model/Datasource/DataSourceTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/DataSourceTest.php @@ -29,7 +29,7 @@ class TestSource extends DataSource { /** * _schema - * @var type + * @var type */ protected $_schema = array( 'id' => array( diff --git a/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php b/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php index f14bf6116..7ae749268 100644 --- a/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php @@ -877,6 +877,52 @@ class MysqlTest extends CakeTestCase { $this->assertContains('`user_id` int(11) NOT NULL,', $result); } +/** + * Test that the primary flag is handled correctly. + * + * @return void + */ + public function testCreateSchemaAutoPrimaryKey() { + $schema = new CakeSchema(); + $schema->tables = array( + 'no_indexes' => array( + 'id' => array('type' => 'integer', 'null' => false, 'key' => 'primary'), + 'data' => array('type' => 'integer', 'null' => false), + 'indexes' => array(), + ) + ); + $result = $this->Dbo->createSchema($schema, 'no_indexes'); + $this->assertContains('PRIMARY KEY (`id`)', $result); + $this->assertNotContains('UNIQUE KEY', $result); + + $schema->tables = array( + 'primary_index' => array( + 'id' => array('type' => 'integer', 'null' => false), + 'data' => array('type' => 'integer', 'null' => false), + 'indexes' => array( + 'PRIMARY' => array('column' => 'id', 'unique' => 1), + 'some_index' => array('column' => 'data', 'unique' => 1) + ), + ) + ); + $result = $this->Dbo->createSchema($schema, 'primary_index'); + $this->assertContains('PRIMARY KEY (`id`)', $result); + $this->assertContains('UNIQUE KEY `some_index` (`data`)', $result); + + $schema->tables = array( + 'primary_flag_has_index' => array( + 'id' => array('type' => 'integer', 'null' => false, 'key' => 'primary'), + 'data' => array('type' => 'integer', 'null' => false), + 'indexes' => array ( + 'some_index' => array('column' => 'data', 'unique' => 1) + ), + ) + ); + $result = $this->Dbo->createSchema($schema, 'primary_flag_has_index'); + $this->assertContains('PRIMARY KEY (`id`)', $result); + $this->assertContains('UNIQUE KEY `some_index` (`data`)', $result); + } + /** * Tests that listSources method sends the correct query and parses the result accordingly * @return void @@ -1914,7 +1960,7 @@ class MysqlTest extends CakeTestCase { $this->assertEquals($expected, $result); $result = $this->Dbo->conditions(array('score' => array(2 => 1, 2, 10))); - $expected = " WHERE score IN (1, 2, 10)"; + $expected = " WHERE `score` IN (1, 2, 10)"; $this->assertEquals($expected, $result); $result = $this->Dbo->conditions("Aro.rght = Aro.lft + 1.1"); @@ -2194,7 +2240,7 @@ class MysqlTest extends CakeTestCase { $this->assertEquals($expected, $result); $result = $this->Dbo->conditions(array('score' => array(1, 2, 10))); - $expected = " WHERE score IN (1, 2, 10)"; + $expected = " WHERE `score` IN (1, 2, 10)"; $this->assertEquals($expected, $result); $result = $this->Dbo->conditions(array('score' => array())); @@ -2285,7 +2331,7 @@ class MysqlTest extends CakeTestCase { 'NOT' => array('Course.id' => null, 'Course.vet' => 'N', 'level_of_education_id' => array(912,999)), 'Enrollment.yearcompleted >' => '0') ); - $this->assertRegExp('/^\s*WHERE\s+\(NOT\s+\(`Course`\.`id` IS NULL\)\s+AND NOT\s+\(`Course`\.`vet`\s+=\s+\'N\'\)\s+AND NOT\s+\(level_of_education_id IN \(912, 999\)\)\)\s+AND\s+`Enrollment`\.`yearcompleted`\s+>\s+\'0\'\s*$/', $result); + $this->assertRegExp('/^\s*WHERE\s+\(NOT\s+\(`Course`\.`id` IS NULL\)\s+AND NOT\s+\(`Course`\.`vet`\s+=\s+\'N\'\)\s+AND NOT\s+\(`level_of_education_id` IN \(912, 999\)\)\)\s+AND\s+`Enrollment`\.`yearcompleted`\s+>\s+\'0\'\s*$/', $result); $result = $this->Dbo->conditions(array('id <>' => '8')); $this->assertRegExp('/^\s*WHERE\s+`id`\s+<>\s+\'8\'\s*$/', $result); @@ -2321,7 +2367,7 @@ class MysqlTest extends CakeTestCase { $conditions = array('id' => array(2, 5, 6, 9, 12, 45, 78, 43, 76)); $result = $this->Dbo->conditions($conditions); - $expected = " WHERE id IN (2, 5, 6, 9, 12, 45, 78, 43, 76)"; + $expected = " WHERE `id` IN (2, 5, 6, 9, 12, 45, 78, 43, 76)"; $this->assertEquals($expected, $result); $conditions = array('title' => 'user(s)'); diff --git a/lib/Cake/Test/Case/Model/Datasource/Database/SqlserverTest.php b/lib/Cake/Test/Case/Model/Datasource/Database/SqlserverTest.php index e31595bf3..ee7695a5f 100644 --- a/lib/Cake/Test/Case/Model/Datasource/Database/SqlserverTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/Database/SqlserverTest.php @@ -574,7 +574,7 @@ class SqlserverTest extends CakeTestCase { $indexes = array('client_id' => array('column' => 'client_id')); $result = $this->db->buildIndex($indexes, 'items'); - $this->assertEquals(array(), $result); + $this->assertSame(array(), $result); $indexes = array('client_id' => array('column' => array('client_id', 'period_id'), 'unique' => 1)); $result = $this->db->buildIndex($indexes, 'items'); diff --git a/lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php b/lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php index de8cc903f..c38e1d085 100644 --- a/lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php @@ -1103,4 +1103,73 @@ class DboSourceTest extends CakeTestCase { $this->assertEquals($expected, $result); } +/** + * Test conditionKeysToString() + * + * @return void + */ + public function testConditionKeysToString() { + $Article = ClassRegistry::init('Article'); + $conn = $this->getMock('MockPDO', array('quote')); + $db = new DboTestSource; + $db->setConnection($conn); + + $conn->expects($this->at(0)) + ->method('quote') + ->will($this->returnValue('just text')); + + $conditions = array('Article.name' => 'just text'); + $result = $db->conditionKeysToString($conditions, true, $Article); + $expected = "Article.name = just text"; + $this->assertEquals($expected, $result[0]); + + $conn->expects($this->at(0)) + ->method('quote') + ->will($this->returnValue('just text')); + $conn->expects($this->at(1)) + ->method('quote') + ->will($this->returnValue('other text')); + + $conditions = array('Article.name' => array('just text', 'other text')); + $result = $db->conditionKeysToString($conditions, true, $Article); + $expected = "Article.name IN (just text, other text)"; + $this->assertEquals($expected, $result[0]); + } + +/** + * Test conditionKeysToString() with virtual field + * + * @return void + */ + public function testConditionKeysToStringVirtualField() { + $Article = ClassRegistry::init('Article'); + $Article->virtualFields = array( + 'extra' => 'something virtual' + ); + $conn = $this->getMock('MockPDO', array('quote')); + $db = new DboTestSource; + $db->setConnection($conn); + + $conn->expects($this->at(0)) + ->method('quote') + ->will($this->returnValue('just text')); + + $conditions = array('Article.extra' => 'just text'); + $result = $db->conditionKeysToString($conditions, true, $Article); + $expected = "(" . $Article->virtualFields['extra'] . ") = just text"; + $this->assertEquals($expected, $result[0]); + + $conn->expects($this->at(0)) + ->method('quote') + ->will($this->returnValue('just text')); + $conn->expects($this->at(1)) + ->method('quote') + ->will($this->returnValue('other text')); + + $conditions = array('Article.extra' => array('just text', 'other text')); + $result = $db->conditionKeysToString($conditions, true, $Article); + $expected = "(" . $Article->virtualFields['extra'] . ") IN (just text, other text)"; + $this->assertEquals($expected, $result[0]); + } + } diff --git a/lib/Cake/Test/Case/Model/ModelDeleteTest.php b/lib/Cake/Test/Case/Model/ModelDeleteTest.php index 329eef387..7a69585c6 100644 --- a/lib/Cake/Test/Case/Model/ModelDeleteTest.php +++ b/lib/Cake/Test/Case/Model/ModelDeleteTest.php @@ -107,12 +107,12 @@ class ModelDeleteTest extends BaseModelTest { $result = $Portfolio->find('first', array( 'conditions' => array('Portfolio.id' => 1) )); - $this->assertFalse($result); + $this->assertSame(array(), $result); $result = $Portfolio->ItemsPortfolio->find('all', array( 'conditions' => array('ItemsPortfolio.portfolio_id' => 1) )); - $this->assertEquals(array(), $result); + $this->assertSame(array(), $result); } /** @@ -195,7 +195,7 @@ class ModelDeleteTest extends BaseModelTest { $this->assertTrue($result); $result = $TestModel->read(null, 2); - $this->assertFalse($result); + $this->assertSame(array(), $result); $TestModel->recursive = -1; $result = $TestModel->find('all', array( @@ -216,7 +216,7 @@ class ModelDeleteTest extends BaseModelTest { $this->assertTrue($result); $result = $TestModel->read(null, 3); - $this->assertFalse($result); + $this->assertSame(array(), $result); $TestModel->recursive = -1; $result = $TestModel->find('all', array( @@ -448,16 +448,16 @@ class ModelDeleteTest extends BaseModelTest { $TestModel->recursive = 2; $result = $TestModel->read(null, 2); - $this->assertFalse($result); + $this->assertSame(array(), $result); $result = $TestModel->Comment->read(null, 5); - $this->assertFalse($result); + $this->assertSame(array(), $result); $result = $TestModel->Comment->read(null, 6); - $this->assertFalse($result); + $this->assertSame(array(), $result); $result = $TestModel->Comment->Attachment->read(null, 1); - $this->assertFalse($result); + $this->assertSame(array(), $result); $result = $TestModel->find('count'); $this->assertEquals(2, $result); diff --git a/lib/Cake/Test/Case/Model/ModelReadTest.php b/lib/Cake/Test/Case/Model/ModelReadTest.php index 7209e0216..fe3780345 100644 --- a/lib/Cake/Test/Case/Model/ModelReadTest.php +++ b/lib/Cake/Test/Case/Model/ModelReadTest.php @@ -4203,7 +4203,8 @@ class ModelReadTest extends BaseModelTest { $this->assertTrue($result); $result = $TestModel->find('all', array( - 'fields' => 'User.id, User.user' + 'fields' => 'User.id, User.user', + 'order' => array('User.id' => 'ASC'), )); $expected = array( array( @@ -4290,13 +4291,14 @@ class ModelReadTest extends BaseModelTest { $TestModel->resetAssociations(); $result = $TestModel->hasMany; - $this->assertEquals(array(), $result); + $this->assertSame(array(), $result); $result = $TestModel->bindModel(array('hasMany' => array('Comment')), false); $this->assertTrue($result); $result = $TestModel->find('all', array( - 'fields' => 'User.id, User.user' + 'fields' => 'User.id, User.user', + 'order' => array('User.id' => 'ASC'), )); $expected = array( @@ -4407,7 +4409,8 @@ class ModelReadTest extends BaseModelTest { $this->assertEquals($expected, $result); $result = $TestModel->find('all', array( - 'fields' => 'User.id, User.user' + 'fields' => 'User.id, User.user', + 'order' => array('User.id' => 'ASC'), )); $expected = array( array('User' => array('id' => '1', 'user' => 'mariano')), @@ -4417,7 +4420,8 @@ class ModelReadTest extends BaseModelTest { $this->assertEquals($expected, $result); $result = $TestModel->find('all', array( - 'fields' => 'User.id, User.user' + 'fields' => 'User.id, User.user', + 'order' => array('User.id' => 'ASC'), )); $expected = array( array( @@ -4505,7 +4509,10 @@ class ModelReadTest extends BaseModelTest { $result = $TestModel->unbindModel(array('hasMany' => array('Comment')), false); $this->assertTrue($result); - $result = $TestModel->find('all', array('fields' => 'User.id, User.user')); + $result = $TestModel->find('all', array( + 'fields' => 'User.id, User.user', + 'order' => array('User.id' => 'ASC'), + )); $expected = array( array('User' => array('id' => '1', 'user' => 'mariano')), array('User' => array('id' => '2', 'user' => 'nate')), @@ -4522,7 +4529,10 @@ class ModelReadTest extends BaseModelTest { ))); $this->assertTrue($result); - $result = $TestModel->find('all', array('fields' => 'User.id, User.user')); + $result = $TestModel->find('all', array( + 'fields' => 'User.id, User.user', + 'order' => array('User.id' => 'ASC'), + )); $expected = array( array( 'User' => array( @@ -4959,7 +4969,9 @@ class ModelReadTest extends BaseModelTest { public function testAssociationAfterFind() { $this->loadFixtures('Post', 'Author', 'Comment'); $TestModel = new Post(); - $result = $TestModel->find('all'); + $result = $TestModel->find('all', array( + 'order' => array('Post.id' => 'ASC') + )); $expected = array( array( 'Post' => array( @@ -5028,6 +5040,7 @@ class ModelReadTest extends BaseModelTest { ))); $result = $Author->find('all', array( 'conditions' => array('Author.id' => 1), + 'order' => array('Author.id' => 'ASC'), 'recursive' => 2 )); $expected = array( @@ -5110,7 +5123,10 @@ class ModelReadTest extends BaseModelTest { public function testAssociationAfterFindCalbacksDisabled() { $this->loadFixtures('Post', 'Author', 'Comment'); $TestModel = new Post(); - $result = $TestModel->find('all', array('callbacks' => false)); + $result = $TestModel->find('all', array( + 'callbacks' => false, + 'order' => array('Post.id' => 'ASC'), + )); $expected = array( array( 'Post' => array( @@ -5177,6 +5193,7 @@ class ModelReadTest extends BaseModelTest { $result = $Author->find('all', array( 'conditions' => array('Author.id' => 1), 'recursive' => 2, + 'order' => array('Author.id' => 'ASC'), 'callbacks' => false )); $expected = array( @@ -6860,6 +6877,17 @@ class ModelReadTest extends BaseModelTest { )); $result = $Article->find('count', array('group' => array('Article.user_id'))); $this->assertEquals($expected, $result); + + $expected = count($Article->find('all', array( + 'fields' => array('Article.user_id'), + 'conditions' => array('Article.user_id' => 1), + 'group' => 'Article.user_id') + )); + $result = $Article->find('count', array( + 'conditions' => array('Article.user_id' => 1), + 'group' => array('Article.user_id'), + )); + $this->assertEquals($expected, $result); } /** @@ -6886,7 +6914,7 @@ class ModelReadTest extends BaseModelTest { $this->skipIf($this->db instanceof Sqlite, 'SELECT COUNT(DISTINCT field) is not compatible with SQLite.'); $this->skipIf($this->db instanceof Sqlserver, 'This test is not compatible with SQL Server.'); - $this->loadFixtures('Project'); + $this->loadFixtures('Project', 'Thread'); $TestModel = new Project(); $TestModel->create(array('name' => 'project')) && $TestModel->save(); $TestModel->create(array('name' => 'project')) && $TestModel->save(); @@ -7745,7 +7773,9 @@ class ModelReadTest extends BaseModelTest { $this->assertEquals($expected, $result); $Post->Author->virtualFields = array('joined' => 'Post.id * Author.id'); - $result = $Post->find('all'); + $result = $Post->find('all', array( + 'order' => array('Post.id' => 'ASC') + )); $result = Hash::extract($result, '{n}.Author.joined'); $expected = array(1, 6, 3); $this->assertEquals($expected, $result); diff --git a/lib/Cake/Test/Case/Model/ModelWriteTest.php b/lib/Cake/Test/Case/Model/ModelWriteTest.php index 31327e7de..1a015ef42 100644 --- a/lib/Cake/Test/Case/Model/ModelWriteTest.php +++ b/lib/Cake/Test/Case/Model/ModelWriteTest.php @@ -4536,7 +4536,7 @@ class ModelWriteTest extends BaseModelTest { $this->assertFalse($result); $result = $model->find('all'); - $this->assertEquals(array(), $result); + $this->assertSame(array(), $result); $expected = array('Comment' => array( 1 => array('comment' => array('This field cannot be left blank')) )); @@ -4725,6 +4725,32 @@ class ModelWriteTest extends BaseModelTest { $this->assertEquals($expected, $TestModel->Comment->validationErrors); } +/** + * test that saveAll still behaves like previous versions (does not necessarily need a first argument) + * + * @return void + */ + public function testSaveAllWithSet() { + $this->loadFixtures('Article', 'Tag', 'Comment', 'User', 'ArticlesTag'); + $data = array( + 'Article' => array( + 'user_id' => 1, + 'title' => 'Article Has and belongs to Many Tags' + ), + 'Tag' => array( + 'Tag' => array(1, 2) + ), + 'Comment' => array( + array( + 'comment' => 'Article comment', + 'user_id' => 1 + ))); + $Article = new Article(); + $Article->set($data); + $result = $Article->saveAll(); + $this->assertFalse(empty($result)); + } + /** * test that saveAll behaves like plain save() when supplied empty data * @@ -4740,7 +4766,7 @@ class ModelWriteTest extends BaseModelTest { $this->assertFalse(empty($result)); $model = new ProductUpdateAll(); - $result = $model->saveAll(array()); + $result = $model->saveAll(); $this->assertFalse($result); } @@ -4830,6 +4856,51 @@ class ModelWriteTest extends BaseModelTest { $this->assertEquals($expected, $result[6]['Attachment']); } +/** + * Test that validate = first, atomic = false works when associated records + * fail validation. + * + * @return void + */ + public function testSaveAssociatedAtomicFalseValidateFirstWithErrors() { + $this->loadFixtures('Comment', 'Article', 'User'); + $Article = ClassRegistry::init('Article'); + $Article->Comment->validator()->add('comment', array( + array('rule' => 'notEmpty') + )); + + $data = array( + 'Article' => array( + 'user_id' => 1, + 'title' => 'Foo', + 'body' => 'text', + 'published' => 'N' + ), + 'Comment' => array( + array( + 'user_id' => 1, + 'comment' => '', + 'published' => 'N', + ) + ), + ); + + $Article->saveAssociated( + $data, + array('validate' => 'first', 'atomic' => false) + ); + + $result = $Article->validationErrors; + $expected = array( + 'Comment' => array( + array( + 'comment' => array( 'This field cannot be left blank' ) + ) + ) + ); + $this->assertEquals($expected, $result); + } + /** * testSaveMany method * @@ -5869,7 +5940,7 @@ class ModelWriteTest extends BaseModelTest { $this->assertFalse($result); $result = $model->find('all'); - $this->assertEquals(array(), $result); + $this->assertSame(array(), $result); $expected = array('Comment' => array( 1 => array('comment' => array('This field cannot be left blank')) )); diff --git a/lib/Cake/Test/Case/Model/Validator/CakeValidationRuleTest.php b/lib/Cake/Test/Case/Model/Validator/CakeValidationRuleTest.php index e0d9c8b35..f4510b9af 100644 --- a/lib/Cake/Test/Case/Model/Validator/CakeValidationRuleTest.php +++ b/lib/Cake/Test/Case/Model/Validator/CakeValidationRuleTest.php @@ -171,4 +171,29 @@ class CakeValidationRuleTest extends CakeTestCase { $Rule->isUpdate(true); $this->assertTrue($Rule->isEmptyAllowed()); } + +/** + * Test checkRequired method + * + * @return void + */ + public function testCheckRequiredWhenRequiredAndAllowEmpty() { + $Rule = $this->getMock('CakeValidationRule', array('isRequired')); + $Rule->expects($this->any()) + ->method('isRequired') + ->will($this->returnValue(true)); + $Rule->allowEmpty = true; + + $fieldname = 'field'; + $data = array( + $fieldname => null + ); + + $this->assertFalse($Rule->checkRequired($fieldname, $data), "A null but present field should not fail requirement check if allowEmpty is true"); + + $Rule->allowEmpty = false; + + $this->assertTrue($Rule->checkRequired($fieldname, $data), "A null but present field should fail requirement check if allowEmpty is false"); + } + } diff --git a/lib/Cake/Test/Case/Model/Validator/CakeValidationSetTest.php b/lib/Cake/Test/Case/Model/Validator/CakeValidationSetTest.php index 10fa6fdf6..aa604fac9 100644 --- a/lib/Cake/Test/Case/Model/Validator/CakeValidationSetTest.php +++ b/lib/Cake/Test/Case/Model/Validator/CakeValidationSetTest.php @@ -156,10 +156,22 @@ class CakeValidationSetTest extends CakeTestCase { $result = $Field->getRules(); $this->assertEquals(array('validEmail'), array_keys($result)); + $Field->setRules(array('validEmail' => $rule), false); + $result = $Field->getRules(); + $this->assertEquals(array('validEmail'), array_keys($result)); + $this->assertTrue(array_pop($result) instanceof CakeValidationRule); + $rules = array('notEmpty' => $RuleEmpty); $Field->setRules($rules, true); $result = $Field->getRules(); $this->assertEquals(array('validEmail', 'notEmpty'), array_keys($result)); + + $rules = array('notEmpty' => array('rule' => 'notEmpty')); + $Field->setRules($rules, true); + $result = $Field->getRules(); + $this->assertEquals(array('validEmail', 'notEmpty'), array_keys($result)); + $this->assertTrue(array_pop($result) instanceof CakeValidationRule); + $this->assertTrue(array_pop($result) instanceof CakeValidationRule); } /** diff --git a/lib/Cake/Test/Case/Network/CakeRequestTest.php b/lib/Cake/Test/Case/Network/CakeRequestTest.php index d4d4c9dda..487f60e80 100644 --- a/lib/Cake/Test/Case/Network/CakeRequestTest.php +++ b/lib/Cake/Test/Case/Network/CakeRequestTest.php @@ -311,9 +311,10 @@ class CakeRequestTest extends CakeTestCase { $request = $this->getMock('TestCakeRequest', array('_readInput')); $request->expects($this->at(0))->method('_readInput') - ->will($this->returnValue('{Article":["title"]}')); + ->will($this->returnValue('{"Article":["title"]}')); $request->reConstruct(); - $this->assertEquals('{Article":["title"]}', $request->data); + $result = $request->input('json_decode', true); + $this->assertEquals(array('title'), $result['Article']); } /** @@ -587,6 +588,24 @@ class CakeRequestTest extends CakeTestCase { $this->assertEquals($request->params['form'], $_FILES); } +/** + * Test that files in the 0th index work. + */ + public function testFilesZeroithIndex() { + $_FILES = array( + 0 => array( + 'name' => 'cake_sqlserver_patch.patch', + 'type' => 'text/plain', + 'tmp_name' => '/private/var/tmp/phpy05Ywj', + 'error' => 0, + 'size' => 6271, + ), + ); + + $request = new CakeRequest('some/path'); + $this->assertEquals($_FILES, $request->params['form']); + } + /** * test method overrides coming in from POST data. * @@ -1628,6 +1647,30 @@ class CakeRequestTest extends CakeTestCase { 'webroot' => '/', ), ), + array( + 'Apache - w/rewrite, document root set above top level cake dir, request root, absolute REQUEST_URI', + array( + 'App' => array( + 'base' => false, + 'baseUrl' => false, + 'dir' => 'app', + 'webroot' => 'webroot' + ), + 'SERVER' => array( + 'SERVER_NAME' => 'localhost', + 'DOCUMENT_ROOT' => '/Library/WebServer/Documents', + 'SCRIPT_FILENAME' => '/Library/WebServer/Documents/site/index.php', + 'REQUEST_URI' => FULL_BASE_URL . '/site/posts/index', + 'SCRIPT_NAME' => '/site/app/webroot/index.php', + 'PHP_SELF' => '/site/app/webroot/index.php', + ), + ), + array( + 'url' => 'posts/index', + 'base' => '/site', + 'webroot' => '/site/', + ), + ), array( 'Nginx - w/rewrite, document root set to webroot, request root, no PATH_INFO', array( @@ -1667,7 +1710,7 @@ class CakeRequestTest extends CakeTestCase { */ public function testEnvironmentDetection($name, $env, $expected) { $_GET = array(); - $this->__loadEnvironment($env); + $this->_loadEnvironment($env); $request = new CakeRequest(); $this->assertEquals($expected['url'], $request->url, "url error"); @@ -1870,7 +1913,7 @@ XML; * @param array $env * @return void */ - protected function __loadEnvironment($env) { + protected function _loadEnvironment($env) { if (isset($env['App'])) { Configure::write('App', $env['App']); } diff --git a/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php b/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php index dfd7db98b..3fc70d742 100644 --- a/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php +++ b/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php @@ -762,6 +762,38 @@ class HttpSocketTest extends CakeTestCase { $this->assertEquals('HTTP/1.x 2', $response->first10); } +/** + * Test that redirect urls are urldecoded + * + * @return void + */ + public function testRequestWithRedirectUrlEncoded() { + $request = array( + 'uri' => 'http://localhost/oneuri', + 'redirect' => 1 + ); + $serverResponse1 = "HTTP/1.x 302 Found\r\nDate: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\nContent-Type: text/html\r\nLocation: http://i.cmpnet.com%2Ftechonline%2Fpdf%2Fa.pdf=\r\n\r\n"; + $serverResponse2 = "HTTP/1.x 200 OK\r\nDate: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\nContent-Type: text/html\r\n\r\n