Merge branch 'master' into 2.5

Conflicts:
	lib/Cake/Routing/Router.php
This commit is contained in:
mark_story 2013-12-08 21:25:59 -05:00
commit 48d2618c62
8 changed files with 125 additions and 8 deletions

View file

@ -1,7 +1,5 @@
<?php
/**
*
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
@ -118,7 +116,7 @@ abstract class BaseAuthenticate {
}
$user = $result[$model];
if ($password) {
if ($password !== null) {
if (!$this->passwordHasher()->check($password, $user[$fields['password']])) {
return false;
}

View file

@ -122,7 +122,7 @@ class CakeEventManager {
* @return void
*/
protected function _attachSubscriber(CakeEventListener $subscriber) {
foreach ($subscriber->implementedEvents() as $eventKey => $function) {
foreach ((array)$subscriber->implementedEvents() as $eventKey => $function) {
$options = array();
$method = $function;
if (is_array($function) && isset($function['callable'])) {
@ -197,7 +197,7 @@ class CakeEventManager {
* @return void
*/
protected function _detachSubscriber(CakeEventListener $subscriber, $eventKey = null) {
$events = $subscriber->implementedEvents();
$events = (array)$subscriber->implementedEvents();
if (!empty($eventKey) && empty($events[$eventKey])) {
return;
} elseif (!empty($eventKey)) {

View file

@ -2701,7 +2701,8 @@ class Model extends Object implements CakeEventListener {
}
$ids = $this->find('all', array_merge(array(
'fields' => "{$this->alias}.{$this->primaryKey}",
'fields' => "DISTINCT {$this->alias}.{$this->primaryKey}",
'order' => false,
'recursive' => 0), compact('conditions'))
);

View file

@ -506,6 +506,12 @@ class Router {
$prefix = $options['prefix'];
$connectOptions = $options['connectOptions'];
unset($options['connectOptions']);
if (strpos($prefix, '/') !== 0) {
$prefix = '/' . $prefix;
}
if (substr($prefix, -1) !== '/') {
$prefix .= '/';
}
foreach ((array)$controller as $name) {
list($plugin, $name) = pluginSplit($name);

View file

@ -118,6 +118,40 @@ class FormAuthenticateTest extends CakeTestCase {
$this->assertFalse($this->auth->authenticate($request, $this->response));
}
/**
* Test for password as empty string with _checkFields() call skipped
* Refs https://github.com/cakephp/cakephp/pull/2441
*
* @return void
*/
public function testAuthenticatePasswordIsEmptyString() {
$request = new CakeRequest('posts/index', false);
$request->data = array(
'User' => array(
'user' => 'mariano',
'password' => ''
));
$this->auth = $this->getMock(
'FormAuthenticate',
array('_checkFields'),
array(
$this->Collection,
array(
'fields' => array('username' => 'user', 'password' => 'password'),
'userModel' => 'User'
)
)
);
// Simulate that check for ensuring password is not empty is missing.
$this->auth->expects($this->once())
->method('_checkFields')
->will($this->returnValue(true));
$this->assertFalse($this->auth->authenticate($request, $this->response));
}
/**
* test authenticate field is not string
*

View file

@ -454,6 +454,70 @@ class ModelDeleteTest extends BaseModelTest {
$this->assertFalse($result);
}
/**
* testDeleteAllMultipleRowsPerId method
*
* Ensure find done in deleteAll only returns distinct ids. A wacky combination
* of association and conditions can sometimes generate multiple rows per id.
*
* @return void
*/
public function testDeleteAllMultipleRowsPerId() {
$this->loadFixtures('Article', 'User');
$TestModel = new Article();
$TestModel->unbindModel(array(
'belongsTo' => array('User'),
'hasMany' => array('Comment'),
'hasAndBelongsToMany' => array('Tag')
), false);
$TestModel->bindModel(array(
'belongsTo' => array(
'User' => array(
'foreignKey' => false,
'conditions' => array(
'Article.user_id = 1'
)
)
)
), false);
$result = $TestModel->deleteAll(
array('Article.user_id' => array(1, 3)),
true,
true
);
$this->assertTrue($result);
}
/**
* testDeleteAllWithOrderProperty
*
* Ensure find done in deleteAll works with models that has $order property set
*
* @return void
*/
public function testDeleteAllWithOrderProperty() {
$this->loadFixtures('Article', 'User');
$TestModel = new Article();
$TestModel->order = 'Article.published desc';
$TestModel->unbindModel(array(
'belongsTo' => array('User'),
'hasMany' => array('Comment'),
'hasAndBelongsToMany' => array('Tag')
), false);
$result = $TestModel->deleteAll(
array('Article.user_id' => array(1, 3)),
true,
true
);
$this->assertTrue($result);
}
/**
* testRecursiveDel method
*

View file

@ -6256,13 +6256,13 @@ class ModelWriteTest extends BaseModelTest {
$TestModel->saveAssociated(array(
'Post' => array(
'title' => $db->expression('(SELECT "Post with Author")'),
'title' => $db->expression("(SELECT 'Post with Author')"),
'body' => 'This post will be saved with an author'
),
'Author' => array(
'user' => 'bob',
'password' => '5f4dcc3b5aa765d61d8327deb882cf90'
)));
)), array('atomic' => false));
$result = $TestModel->find('first', array(
'order' => array('Post.id ' => 'DESC')

View file

@ -237,6 +237,20 @@ class RouterTest extends CakeTestCase {
);
$this->assertEquals($expected, $result);
$this->assertEquals(array('test_plugin'), $resources);
$resources = Router::mapResources('Posts', array('prefix' => 'api'));
$_SERVER['REQUEST_METHOD'] = 'GET';
$result = Router::parse('/api/posts');
$expected = array(
'pass' => array(),
'named' => array(),
'plugin' => null,
'controller' => 'posts',
'action' => 'index',
'[method]' => 'GET'
);
$this->assertEquals($expected, $result);
}
/**