Browse Source

Merge pull request #5928 from cakephp/issue-5922

Guard against missing new entities.
José Lorenzo Rodríguez 11 years ago
parent
commit
03fded17a1
2 changed files with 71 additions and 3 deletions
  1. 5 3
      src/ORM/Marshaller.php
  2. 66 0
      tests/TestCase/ORM/MarshallerTest.php

+ 5 - 3
src/ORM/Marshaller.php

@@ -470,11 +470,13 @@ class Marshaller
                 return $query->orWhere($query->newExpr()->and_(array_combine($primary, $keys)));
             }, $this->_table->find());
 
-        if (count($maybeExistentQuery->clause('where'))) {
+        if (!empty($indexed) && count($maybeExistentQuery->clause('where'))) {
             foreach ($maybeExistentQuery as $entity) {
                 $key = implode(';', $entity->extract($primary));
-                $output[] = $this->merge($entity, $indexed[$key], $options);
-                unset($indexed[$key]);
+                if (isset($indexed[$key])) {
+                    $output[] = $this->merge($entity, $indexed[$key], $options);
+                    unset($indexed[$key]);
+                }
             }
         }
 

+ 66 - 0
tests/TestCase/ORM/MarshallerTest.php

@@ -47,6 +47,40 @@ class ProtectedArticle extends Entity
 }
 
 /**
+ * Test stub for greedy find operations.
+ */
+class GreedyCommentsTable extends Table
+{
+    /**
+     * initialize hook
+     *
+     * @param $config Config data.
+     * @return void
+     */
+    public function initialize(array $config)
+    {
+        $this->table('comments');
+        $this->alias('Comments');
+    }
+
+    /**
+     * Overload find to cause issues.
+     *
+     * @param string $type Find type
+     * @param array $options find options
+     * @return object
+     */
+    public function find($type = 'all', $options = [])
+    {
+        if (empty($options['conditions'])) {
+            $options['conditions'] = [];
+        }
+        $options['conditions'] = array_merge($options['conditions'], ['Comments.published' => 'Y']);
+        return parent::find($type, $options);
+    }
+}
+
+/**
  * Marshaller test case
  */
 class MarshallerTest extends TestCase
@@ -1282,6 +1316,38 @@ class MarshallerTest extends TestCase
     }
 
     /**
+     * Test mergeMany() when the exist check returns nothing.
+     *
+     * @return void
+     */
+    public function testMergeManyExistQueryFails()
+    {
+        $entities = [
+            new Entity(['id' => 1, 'comment' => 'First post', 'user_id' => 2]),
+            new Entity(['id' => 2, 'comment' => 'Second post', 'user_id' => 2])
+        ];
+        $entities[0]->clean();
+        $entities[1]->clean();
+
+        $data = [
+            ['id' => 2, 'comment' => 'Changed 2', 'user_id' => 2],
+            ['id' => 1, 'comment' => 'Changed 1', 'user_id' => 1],
+            ['id' => 3, 'comment' => 'New 1'],
+        ];
+        $comments = TableRegistry::get('GreedyComments', [
+            'className' => __NAMESPACE__ . '\\GreedyCommentsTable'
+        ]);
+        $marshall = new Marshaller($comments);
+        $result = $marshall->mergeMany($entities, $data);
+
+        $this->assertCount(3, $result);
+        $this->assertEquals('Changed 1', $result[0]->comment);
+        $this->assertEquals(1, $result[0]->user_id);
+        $this->assertEquals('Changed 2', $result[1]->comment);
+        $this->assertEquals('New 1', $result[2]->comment);
+    }
+
+    /**
      * Tests merge with data types that need to be marshalled
      *
      * @return void