ソースを参照

Fix null not stopping model callbacks.

Add a compatibility shim into CakeEventManager to fix `null` not
breaking model callbacks.  This was a regression created when model
callbacks were re-factored to use the event manager. This code should be
removed in 3.x as its inconsistent with events used everywhere else in
the framework.

Fixes #3123
mark_story 13 年 前
コミット
82a8400def

+ 4 - 0
lib/Cake/Event/CakeEventManager.php

@@ -248,6 +248,10 @@ class CakeEventManager {
 			if ($result === false) {
 				$event->stopPropagation();
 			}
+			// TODO remove this in 3.0 as its a compatibility shim for model callbacks.
+			if (isset($event->break, $event->breakOn) && in_array($result, (array)$event->breakOn)) {
+				$event->stopPropagation();
+			}
 			if ($result !== null) {
 				$event->result = $result;
 			}

+ 1 - 1
lib/Cake/Model/Model.php

@@ -1667,7 +1667,7 @@ class Model extends Object implements CakeEventListener {
 			$event = new CakeEvent('Model.beforeSave', $this, array($options));
 			list($event->break, $event->breakOn) = array(true, array(false, null));
 			$this->getEventManager()->dispatch($event);
-			if (!$event->result) {
+			if ($event->isStopped()) {
 				$this->whitelist = $_whitelist;
 				return false;
 			}

+ 39 - 0
lib/Cake/Test/Case/Model/ModelWriteTest.php

@@ -540,6 +540,25 @@ class ModelWriteTest extends BaseModelTest {
 	}
 
 /**
+ * test that beforeValidate returning false can abort saves.
+ *
+ * @return void
+ */
+	public function testBeforeValidateNullSaveAbortion() {
+		$this->loadFixtures('Post');
+		$Model = new CallbackPostTestModel();
+		$Model->beforeValidateReturn = null;
+
+		$data = array(
+			'title' => 'new article',
+			'body' => 'this is some text.'
+		);
+		$Model->create();
+		$result = $Model->save($data);
+		$this->assertFalse($result);
+	}
+
+/**
  * test that beforeSave returning false can abort saves.
  *
  * @return void
@@ -559,6 +578,26 @@ class ModelWriteTest extends BaseModelTest {
 	}
 
 /**
+ * Test that beforeSave returnning null can abort saves.
+ *
+ * @return void
+ */
+	public function testBeforeSaveNullAbort() {
+		$this->loadFixtures('Post');
+		$Model = new CallbackPostTestModel();
+		$Model->beforeSaveReturn = null;
+
+		$data = array(
+			'title' => 'new article',
+			'body' => 'this is some text.'
+		);
+		$Model->create();
+		$result = $Model->save($data);
+		$this->assertFalse($result);
+
+	}
+
+/**
  * testSaveField method
  *
  * @return void