From 51dc9cf9bbadedfda79583f1a34419a4849611f9 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Thu, 9 Apr 2015 21:06:58 -0400 Subject: [PATCH] Skip non-entity entries in BelongsToMany associations When saving entities with accessible belongs to many association properties that were not marshalled, fatal errors would be encountered. Skipping the obviously bad data is a resonable course of action as the ORM should not marshall it, as it was either explicitly or implicitly not marshalled. Refs #6301 --- src/ORM/Association/BelongsToMany.php | 6 ++++++ .../ORM/Association/BelongsToManyTest.php | 2 +- tests/TestCase/ORM/TableTest.php | 16 ++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/ORM/Association/BelongsToMany.php b/src/ORM/Association/BelongsToMany.php index 3cfd11e365e..1d28068b606 100644 --- a/src/ORM/Association/BelongsToMany.php +++ b/src/ORM/Association/BelongsToMany.php @@ -804,6 +804,9 @@ protected function _diffLinks($existing, $jointEntities, $targetEntities) $primary = (array)$target->primaryKey(); $jointProperty = $this->_junctionProperty; foreach ($targetEntities as $k => $entity) { + if (!($entity instanceof EntityInterface)) { + continue; + } $key = array_values($entity->extract($primary)); foreach ($present as $i => $data) { if ($key === $data && !$entity->get($jointProperty)) { @@ -873,6 +876,9 @@ protected function _collectJointEntities($sourceEntity, $targetEntities) $missing = []; foreach ($targetEntities as $entity) { + if (!($entity instanceof EntityInterface)) { + continue; + } $joint = $entity->get($jointProperty); if (!$joint || !($joint instanceof EntityInterface)) { diff --git a/tests/TestCase/ORM/Association/BelongsToManyTest.php b/tests/TestCase/ORM/Association/BelongsToManyTest.php index 6f11659e547..a706c1ce5ee 100644 --- a/tests/TestCase/ORM/Association/BelongsToManyTest.php +++ b/tests/TestCase/ORM/Association/BelongsToManyTest.php @@ -912,7 +912,7 @@ public function testSaveAssociatedWithReplaceReturnFalse() * * @return void */ - public function testSaveAssociatedOnlyEntities() + public function testSaveAssociatedOnlyEntitiesAppend() { $connection = ConnectionManager::get('test'); $mock = $this->getMock( diff --git a/tests/TestCase/ORM/TableTest.php b/tests/TestCase/ORM/TableTest.php index 265d276f1cf..8f8ead87913 100644 --- a/tests/TestCase/ORM/TableTest.php +++ b/tests/TestCase/ORM/TableTest.php @@ -3170,6 +3170,22 @@ public function testSaveBelongsToManyDeleteSomeLinks() $this->assertEquals($tag->id, $entity->tags[0]->id); } + /** + * Test that belongsToMany ignores non-entity data. + * + * @return void + */ + public function testSaveBelongsToManyIgnoreNonEntityData() + { + $articles = TableRegistry::get('Articles'); + $article = $articles->get(1, ['contain' => ['Tags']]); + $article->tags = [ + '_ids' => [2, 1] + ]; + $result = $articles->save($article); + $this->assertSame($result, $article); + } + /** * Tests that saving a persisted and clean entity will is a no-op *