浏览代码

Improve PasswordableBehavior for >=2.5

euromark 12 年之前
父节点
当前提交
6081015d89
共有 3 个文件被更改,包括 73 次插入31 次删除
  1. 26 6
      Model/Behavior/PasswordableBehavior.php
  2. 29 17
      README.md
  3. 18 8
      Test/Case/Model/Behavior/PasswordableBehaviorTest.php

+ 26 - 6
Model/Behavior/PasswordableBehavior.php

@@ -343,6 +343,9 @@ class PasswordableBehavior extends ModelBehavior {
 			}
 			}
 		}
 		}
 
 
+		// Update whitelist
+		$this->_modifyWhitelist($Model);
+
 		return true;
 		return true;
 	}
 	}
 
 
@@ -377,21 +380,38 @@ class PasswordableBehavior extends ModelBehavior {
 		}
 		}
 
 
 		// Update whitelist
 		// Update whitelist
-		$this->_modifyWhitelist($Model);
+		$this->_modifyWhitelist($Model, true);
 
 
 		return true;
 		return true;
 	}
 	}
 
 
 	/**
 	/**
-	 * PasswordableBehavior::_modifyWhitelist()
+	 * Modify the model's whitelist.
+	 *
+	 * Since 2.5 behaviors can also modify the whitelist for validate, thus this behavior can now
+	 * (>= CakePHP 2.5) add the form fields automatically, as well (not just the password field itself).
 	 *
 	 *
 	 * @param Model $Model
 	 * @param Model $Model
 	 * @return void
 	 * @return void
 	 */
 	 */
-	protected function _modifyWhitelist(Model $Model) {
-		$field = $this->settings[$Model->alias]['field'];
-		if (!empty($Model->whitelist) && !in_array($field, $Model->whitelist)) {
-			$Model->whitelist = array_merge($Model->whitelist, array($field));
+	protected function _modifyWhitelist(Model $Model, $onSave = false) {
+		$fields = array();
+		if ($onSave) {
+			$fields[] = $this->settings[$Model->alias]['field'];
+		} else {
+			$fields[] = $this->settings[$Model->alias]['formField'];
+			if ($this->settings[$Model->alias]['confirm']) {
+				$fields[] = $this->settings[$Model->alias]['formFieldRepeat'];
+			}
+			if ($this->settings[$Model->alias]['current']) {
+				$fields[] = $this->settings[$Model->alias]['formFieldCurrent'];
+			}
+		}
+
+		foreach ($fields as $field) {
+			if (!empty($Model->whitelist) && !in_array($field, $Model->whitelist)) {
+				$Model->whitelist = array_merge($Model->whitelist, array($field));
+			}
 		}
 		}
 	}
 	}
 
 

+ 29 - 17
README.md

@@ -18,38 +18,48 @@ That's it. It should be up and running.
 
 
 Include the Tools bootstrap file in your `APP/Config/bootstrap.php` with
 Include the Tools bootstrap file in your `APP/Config/bootstrap.php` with
 
 
-    App::import('Lib', 'Tools.Bootstrap/MyBootstrap');
+```php
+App::import('Lib', 'Tools.Bootstrap/MyBootstrap');
+```
 
 
 You cannot use App::uses because this file does not contain a class and needs to be included right away (not lazy loaded).
 You cannot use App::uses because this file does not contain a class and needs to be included right away (not lazy loaded).
 
 
 
 
 MyModel can be extended to use more powerful validation and other improvements:
 MyModel can be extended to use more powerful validation and other improvements:
 
 
-    App::uses('MyModel', 'Tools.Model');
+```php
+App::uses('MyModel', 'Tools.Model');
 
 
-    class AppModel extends MyModel {
-    }
+class AppModel extends MyModel {
+}
+```
 
 
 MyController can be extended for DRY improvements and to fix some common bugs:
 MyController can be extended for DRY improvements and to fix some common bugs:
 
 
-    App::uses('MyController', 'Tools.Controller');
+```php
+App::uses('MyController', 'Tools.Controller');
 
 
-    class MyController extends MyController {
-    }
+class MyController extends MyController {
+}
+```
 
 
 MyHelper can be extended and used this way:
 MyHelper can be extended and used this way:
 
 
-    App::uses('MyHelper', 'Tools.View/Helper');
+```php
+App::uses('MyHelper', 'Tools.View/Helper');
 
 
-    class AppHelper extends MyHelper {
-    }
+class AppHelper extends MyHelper {
+}
+```
 
 
 The test suite improvements can be used via:
 The test suite improvements can be used via:
 
 
-    App::uses('MyCakeTestCase', 'Tools.TestSuite');
+```php
+App::uses('MyCakeTestCase', 'Tools.TestSuite');
 
 
-    class SomeClassTest extends MyCakeTestCase {
-    }
+class SomeClassTest extends MyCakeTestCase {
+}
+```
 
 
 To run any of the console commands (replace [ShellName] and [command]!):
 To run any of the console commands (replace [ShellName] and [command]!):
 
 
@@ -57,10 +67,12 @@ To run any of the console commands (replace [ShellName] and [command]!):
 
 
 The models, behaviors, helpers, libs and other classes are used the same way prefixing them with the plugin name:
 The models, behaviors, helpers, libs and other classes are used the same way prefixing them with the plugin name:
 
 
-    App::uses('GooglLib', 'Tools.Lib');
-    App::uses('TimeLib', 'Tools.Utility');
-    App::uses('GeocoderBehavior', 'Tools.Model/Behavior');
-    ...
+```php
+App::uses('GooglLib', 'Tools.Lib');
+App::uses('TimeLib', 'Tools.Utility');
+App::uses('GeocoderBehavior', 'Tools.Model/Behavior');
+...
+```
 
 
 Tip: For how to use them, try to find some information in the test cases.
 Tip: For how to use them, try to find some information in the test cases.
 Usage for some larger modules: https://github.com/dereuromark/tools/blob/master/USAGE
 Usage for some larger modules: https://github.com/dereuromark/tools/blob/master/USAGE

+ 18 - 8
Test/Case/Model/Behavior/PasswordableBehaviorTest.php

@@ -56,7 +56,7 @@ class PasswordableBehaviorTest extends CakeTestCase {
 	public function testObject() {
 	public function testObject() {
 		$this->User->Behaviors->load('Tools.Passwordable', array());
 		$this->User->Behaviors->load('Tools.Passwordable', array());
 		$this->assertInstanceOf('PasswordableBehavior', $this->User->Behaviors->Passwordable);
 		$this->assertInstanceOf('PasswordableBehavior', $this->User->Behaviors->Passwordable);
-		$res = $this->User->Behaviors->attached('Passwordable');
+		$res = $this->User->Behaviors->loaded('Passwordable');
 		$this->assertTrue($res);
 		$this->assertTrue($res);
 	}
 	}
 
 
@@ -302,7 +302,7 @@ class PasswordableBehaviorTest extends CakeTestCase {
 	 * Needs faking of pwd check...
 	 * Needs faking of pwd check...
 	 */
 	 */
 	public function testValidateCurrent() {
 	public function testValidateCurrent() {
-		$this->assertFalse($this->User->Behaviors->attached('Passwordable'));
+		$this->assertFalse($this->User->Behaviors->loaded('Passwordable'));
 		$this->User->create();
 		$this->User->create();
 		$data = array(
 		$data = array(
 			'name' => 'xyz',
 			'name' => 'xyz',
@@ -320,7 +320,7 @@ class PasswordableBehaviorTest extends CakeTestCase {
 			//'pwd_current' => '',
 			//'pwd_current' => '',
 		);
 		);
 		$this->User->set($data);
 		$this->User->set($data);
-		$this->assertTrue($this->User->Behaviors->attached('Passwordable'));
+		$this->assertTrue($this->User->Behaviors->loaded('Passwordable'));
 		$is = $this->User->save();
 		$is = $this->User->save();
 		$this->assertFalse($is);
 		$this->assertFalse($is);
 
 
@@ -353,7 +353,7 @@ class PasswordableBehaviorTest extends CakeTestCase {
 		$this->assertSame($is['ToolsUser']['password'], $user['ToolsUser']['password']);
 		$this->assertSame($is['ToolsUser']['password'], $user['ToolsUser']['password']);
 		$this->assertSame('xyz', $user['ToolsUser']['name']);
 		$this->assertSame('xyz', $user['ToolsUser']['name']);
 
 
-		// Proof that we manually need to add pwd, pwd_repeat etc due to a bug in Cake allowing behaviors to only modify saving,
+		// Proof that we manually need to add pwd, pwd_repeat etc due to a bug in CakePHP<=2.4 allowing behaviors to only modify saving,
 		// not validating of additional whitelist fields. Validation for those will be just skipped, no matter what the behavior tries
 		// not validating of additional whitelist fields. Validation for those will be just skipped, no matter what the behavior tries
 		// to set.
 		// to set.
 		$this->User->create();
 		$this->User->create();
@@ -369,13 +369,23 @@ class PasswordableBehaviorTest extends CakeTestCase {
 		// NOTE that I had to remove the code for adding those fields from the behavior (as it was not functional)
 		// NOTE that I had to remove the code for adding those fields from the behavior (as it was not functional)
 		// So of course, this won't work now as expected. But feel free to try to add them in the behavior. Results will be the same.
 		// So of course, this won't work now as expected. But feel free to try to add them in the behavior. Results will be the same.
 		$is = $this->User->save(null, true, array('id', 'name'));
 		$is = $this->User->save(null, true, array('id', 'name'));
+
+		if ((float)Configure::version() >= 2.5) {
+			// Validation errors triggered - as expected
+			$this->assertFalse($is);
+			$this->assertSame(array('pwd', 'pwd_repeat', 'pwd_current'), array_keys($this->User->validationErrors));
+			return;
+		}
+
 		// Save is successful
 		// Save is successful
 		$this->assertTrue(!empty($is));
 		$this->assertTrue(!empty($is));
-
 		$user = $this->User->get($uid);
 		$user = $this->User->get($uid);
+
+		$this->assertSame('Yeah', $user['ToolsUser']['name']);
+
 		// The password is not updated, the name is
 		// The password is not updated, the name is
 		$this->assertSame($is['ToolsUser']['password'], $user['ToolsUser']['password']);
 		$this->assertSame($is['ToolsUser']['password'], $user['ToolsUser']['password']);
-		$this->assertSame('Yeah', $user['ToolsUser']['name']);
+		$this->assertNotSame($is['ToolsUser']['password'], $user['ToolsUser']['password']);
 	}
 	}
 
 
 	/**
 	/**
@@ -412,7 +422,7 @@ class PasswordableBehaviorTest extends CakeTestCase {
 			//'pwd_current' => '',
 			//'pwd_current' => '',
 		);
 		);
 		$this->User->set($data);
 		$this->User->set($data);
-		$this->assertTrue($this->User->Behaviors->attached('Passwordable'));
+		$this->assertTrue($this->User->Behaviors->loaded('Passwordable'));
 		$is = $this->User->save();
 		$is = $this->User->save();
 		$this->assertFalse($is);
 		$this->assertFalse($is);
 
 
@@ -468,7 +478,7 @@ class PasswordableBehaviorTest extends CakeTestCase {
 			'pwd_repeat' => '12345678',
 			'pwd_repeat' => '12345678',
 		);
 		);
 		$this->User->set($data);
 		$this->User->set($data);
-		$this->assertTrue($this->User->Behaviors->attached('Passwordable'));
+		$this->assertTrue($this->User->Behaviors->loaded('Passwordable'));
 		$is = $this->User->save();
 		$is = $this->User->save();
 		$this->assertFalse($is);
 		$this->assertFalse($is);