Browse Source

Merge branch 'master' into 2.3

Conflicts:
	lib/Cake/Test/Case/View/MediaViewTest.php
mark_story 13 years ago
parent
commit
60f9626838

+ 2 - 0
lib/Cake/Controller/CakeErrorController.php

@@ -20,6 +20,8 @@
  */
 App::uses('AppController', 'Controller');
 
+App::uses('AppController', 'Controller');
+
 /**
  * Error Handling Controller
  *

+ 7 - 2
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();

+ 2 - 3
lib/Cake/Error/ExceptionRenderer.php

@@ -138,6 +138,7 @@ class ExceptionRenderer {
  * @return Controller
  */
 	protected function _getController($exception) {
+		App::uses('AppController', 'Controller');
 		App::uses('CakeErrorController', 'Controller');
 		if (!$request = Router::getRequest(true)) {
 			$request = new CakeRequest();
@@ -149,9 +150,7 @@ class ExceptionRenderer {
 		}
 
 		try {
-			if (class_exists('AppController')) {
-				$controller = new CakeErrorController($request, $response);
-			}
+			$controller = new CakeErrorController($request, $response);
 		} catch (Exception $e) {
 		}
 		if (empty($controller)) {

+ 15 - 0
lib/Cake/Model/Behavior/TranslateBehavior.php

@@ -385,6 +385,21 @@ class TranslateBehavior extends ModelBehavior {
 	}
 
 /**
+ * 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
  *
  * @param Model $Model Model the callback is called on

+ 8 - 8
lib/Cake/Model/Datasource/DboSource.php

@@ -2489,16 +2489,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) {

+ 6 - 5
lib/Cake/Network/CakeRequest.php

@@ -162,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);

+ 1 - 1
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);
 		}

+ 18 - 1
lib/Cake/Test/Case/Core/ObjectTest.php

@@ -620,6 +620,24 @@ class ObjectTest extends CakeTestCase {
 	}
 
 /**
+ * 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(

+ 0 - 1
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');
 

+ 32 - 0
lib/Cake/Test/Case/Model/Behavior/TranslateBehaviorTest.php

@@ -531,6 +531,38 @@ class TranslateBehaviorTest extends CakeTestCase {
 	}
 
 /**
+ * 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.
  *
  * @return void

+ 43 - 24
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);

+ 4 - 4
lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php

@@ -2009,7 +2009,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");
@@ -2289,7 +2289,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()));
@@ -2380,7 +2380,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);
@@ -2416,7 +2416,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)');

+ 69 - 0
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]);
+	}
+
 }

+ 3 - 2
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']);
 	}
 
 /**

+ 42 - 0
lib/Cake/Test/Case/Network/Http/HttpSocketTest.php

@@ -763,6 +763,38 @@ class HttpSocketTest extends CakeTestCase {
 	}
 
 /**
+ * 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<h1>You have been redirected</h1>";
+
+		$this->Socket->expects($this->at(1))
+			->method('read')
+			->will($this->returnValue($serverResponse1));
+
+		$this->Socket->expects($this->at(3))
+			->method('write')
+			->with($this->logicalAnd(
+				$this->stringContains('Host: i.cmpnet.com'),
+				$this->stringContains('GET /techonline/pdf/a.pdf')
+			));
+
+		$this->Socket->expects($this->at(4))
+			->method('read')
+			->will($this->returnValue($serverResponse2));
+
+		$response = $this->Socket->request($request);
+		$this->assertEquals('<h1>You have been redirected</h1>', $response->body());
+	}
+
+/**
  * testRequestWithRedirect method
  *
  * @return void
@@ -781,6 +813,11 @@ class HttpSocketTest extends CakeTestCase {
 		$this->assertEquals('<h1>You have been redirected</h1>', $response->body());
 	}
 
+/**
+ * Test that redirects with a count limit are decremented.
+ *
+ * @return void
+ */
 	public function testRequestWithRedirectAsInt() {
 		$request = array(
 			'uri' => 'http://localhost/oneuri',
@@ -795,6 +832,11 @@ class HttpSocketTest extends CakeTestCase {
 		$this->assertEquals(1, $this->Socket->request['redirect']);
 	}
 
+/**
+ * Test that redirects after the redirect count reaches 9 are not followed.
+ *
+ * @return void
+ */
 	public function testRequestWithRedirectAsIntReachingZero() {
 		$request = array(
 			'uri' => 'http://localhost/oneuri',

+ 18 - 0
lib/Cake/Test/Case/View/Helper/FormHelperTest.php

@@ -116,6 +116,10 @@ class Contact extends CakeTestModel {
 		'imnotrequired' => array('required' => false, 'rule' => 'alphaNumeric', 'allowEmpty' => true),
 		'imalsonotrequired' => array(
 			'alpha' => array('rule' => 'alphaNumeric', 'allowEmpty' => true),
+			'between' => array('rule' => array('between', 5, 30)),
+		),
+		'imalsonotrequired2' => array(
+			'alpha' => array('rule' => 'alphaNumeric', 'allowEmpty' => true),
 			'between' => array('rule' => array('between', 5, 30), 'allowEmpty' => true),
 		),
 		'imnotrequiredeither' => array('required' => true, 'rule' => array('between', 5, 30), 'allowEmpty' => true),
@@ -7162,6 +7166,20 @@ class FormHelperTest extends CakeTestCase {
 		);
 		$this->assertTags($result, $expected);
 
+		$result = $this->Form->input('Contact.imalsonotrequired2');
+		$expected = array(
+			'div' => array('class' => 'input text'),
+			'label' => array('for' => 'ContactImalsonotrequired2'),
+			'Imalsonotrequired2',
+			'/label',
+			'input' => array(
+				'type' => 'text', 'name' => 'data[Contact][imalsonotrequired2]',
+				'id' => 'ContactImalsonotrequired2'
+			),
+			'/div'
+		);
+		$this->assertTags($result, $expected);
+
 		$result = $this->Form->input('Contact.imnotrequiredeither');
 		$expected = array(
 			'div' => array('class' => 'input text'),

+ 6 - 4
lib/Cake/Test/Case/View/MediaViewTest.php

@@ -135,10 +135,12 @@ class MediaViewTest extends CakeTestCase {
 
 		$this->MediaView->response->expects($this->at(0))
 			->method('header')
-			->with(array(
-				'Expires' => 'Mon, 26 Jul 1997 05:00:00 GMT',
-				'Cache-Control' => 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0',
-				'Last-Modified' => gmdate('D, d M Y H:i:s', time()) . ' GMT'
+			->with($this->logicalAnd(
+				$this->arrayHasKey('Last-Modified'),
+				$this->arrayHasKey('Expires'),
+				$this->arrayHasKey('Cache-Control'),
+				$this->contains('Mon, 26 Jul 1997 05:00:00 GMT'),
+				$this->contains('no-store, no-cache, must-revalidate, post-check=0, pre-check=0')
 			));
 
 		$this->MediaView->response->expects($this->once())

+ 5 - 5
lib/Cake/Test/Fixture/FlagTreeFixture.php

@@ -41,11 +41,11 @@ class FlagTreeFixture extends CakeTestFixture {
  * @var array
  */
 	public $fields = array(
-		'id'	=> array('type' => 'integer','key' => 'primary'),
-		'name'	=> array('type' => 'string','null' => false),
+		'id' => array('type' => 'integer','key' => 'primary'),
+		'name' => array('type' => 'string','null' => false),
 		'parent_id' => 'integer',
-		'lft'	=> array('type' => 'integer','null' => false),
-		'rght'	=> array('type' => 'integer','null' => false),
-		'flag'	=> array('type' => 'integer','null' => false, 'length' => 1, 'default' => 0)
+		'lft' => array('type' => 'integer','null' => false),
+		'rght' => array('type' => 'integer','null' => false),
+		'flag' => array('type' => 'integer','null' => false, 'length' => 1, 'default' => 0)
 	);
 }

+ 1 - 1
lib/Cake/Utility/Inflector.php

@@ -177,7 +177,7 @@ class Inflector {
 		'/Ä/' => 'Ae',
 		'/Ü/' => 'Ue',
 		'/Ö/' => 'Oe',
-		'/À|Á|Â|Ã|Ä|Å|Ǻ|Ā|Ă|Ą|Ǎ/' => 'A',
+		'/À|Á|Â|Ã|Å|Ǻ|Ā|Ă|Ą|Ǎ/' => 'A',
 		'/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª/' => 'a',
 		'/Ç|Ć|Ĉ|Ċ|Č/' => 'C',
 		'/ç|ć|ĉ|ċ|č/' => 'c',

+ 7 - 3
lib/Cake/View/Helper/FormHelper.php

@@ -247,11 +247,15 @@ class FormHelper extends AppHelper {
 		if (empty($validationRules) || count($validationRules) === 0) {
 			return false;
 		}
+
+		$isUpdate = $this->requestType === 'put';
 		foreach ($validationRules as $rule) {
-			$rule->isUpdate($this->requestType === 'put');
-			if (!$rule->isEmptyAllowed()) {
-				return true;
+			$rule->isUpdate($isUpdate);
+			if ($rule->skip()) {
+				continue;
 			}
+
+			return !$rule->allowEmpty;
 		}
 		return false;
 	}