From 39011cd9d8def8308629991af5f5bda0d01040d1 Mon Sep 17 00:00:00 2001 From: mark_story Date: Thu, 9 Oct 2014 22:49:17 -0400 Subject: [PATCH] Fix Model::isUnique() not working as a validator. While it *did* work for single fields, isUnique could not be used to validate the uniqueness across multiple fields as documented. Because validation methods pass arguments in an order the validator did not expect the validation method would not work correctly. Fixes #4571 --- lib/Cake/Model/Model.php | 10 ++++- .../Test/Case/Model/ModelValidationTest.php | 44 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Model/Model.php b/lib/Cake/Model/Model.php index 3a698101b..c9e7ce7e9 100644 --- a/lib/Cake/Model/Model.php +++ b/lib/Cake/Model/Model.php @@ -3293,11 +3293,19 @@ class Model extends Object implements CakeEventListener { /** * Returns false if any fields passed match any (by default, all if $or = false) of their matching values. * + * Can be used as a validation method. When used as a validation method, the `$or` parameter + * contains an array of fields to be validated. + * * @param array $fields Field/value pairs to search (if no values specified, they are pulled from $this->data) - * @param bool $or If false, all fields specified must match in order for a false return value + * @param bool|array $or If false, all fields specified must match in order for a false return value * @return bool False if any records matching any fields are found */ public function isUnique($fields, $or = true) { + if (is_array($or)) { + $args = func_get_args(); + $fields = $args[1]; + $or = isset($args[2]) ? $args[2] : true; + } if (!is_array($fields)) { $fields = func_get_args(); if (is_bool($fields[count($fields) - 1])) { diff --git a/lib/Cake/Test/Case/Model/ModelValidationTest.php b/lib/Cake/Test/Case/Model/ModelValidationTest.php index 8a3d266fd..c5f3b22a3 100644 --- a/lib/Cake/Test/Case/Model/ModelValidationTest.php +++ b/lib/Cake/Test/Case/Model/ModelValidationTest.php @@ -2405,6 +2405,50 @@ class ModelValidationTest extends BaseModelTest { $this->assertEquals($expected, $result); } +/** + * Test the isUnique method when used as a validator for multiple fields. + * + * @return void + */ + public function testIsUniqueValidator() { + $this->loadFixtures('Article'); + $Article = ClassRegistry::init('Article'); + $Article->validate = array( + 'user_id' => array( + 'duplicate' => array( + 'rule' => array('isUnique', array('user_id', 'title'), false) + ) + ) + ); + $data = array( + 'user_id' => 1, + 'title' => 'First Article', + ); + $Article->create($data); + $this->assertFalse($Article->validates(), 'Contains a dupe'); + + $data = array( + 'user_id' => 1, + 'title' => 'Unique Article', + ); + $Article->create($data); + $this->assertTrue($Article->validates(), 'Should pass'); + + $Article->validate = array( + 'user_id' => array( + 'duplicate' => array( + 'rule' => array('isUnique', array('user_id', 'title')) + ) + ) + ); + $data = array( + 'user_id' => 1, + 'title' => 'Unique Article', + ); + $Article->create($data); + $this->assertFalse($Article->validates(), 'Should fail, conditions are combined with or'); + } + } /**