Skip to content

Commit

Permalink
Fix error in marshalling belongsToMany relations.
Browse files Browse the repository at this point in the history
When removing all belongsTo associations `_ids` can be an empty scalar
value. The marshaller should handle empty scalar values gracefully.

Refs #3485
  • Loading branch information
markstory committed May 19, 2014
1 parent e16a34a commit 85aecb6
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 2 deletions.
8 changes: 6 additions & 2 deletions src/ORM/Marshaller.php
Expand Up @@ -170,7 +170,7 @@ public function many(array $data, array $include = []) {
* @return array An array of built entities.
*/
protected function _belongsToMany(Association $assoc, array $data, $include = []) {
$hasIds = isset($data['_ids']);
$hasIds = array_key_exists('_ids', $data);
if ($hasIds && is_array($data['_ids'])) {
return $this->_loadBelongsToMany($assoc, $data['_ids']);
}
Expand Down Expand Up @@ -361,9 +361,13 @@ protected function _mergeAssociation($original, $assoc, $value, $include) {
* @return mixed
*/
protected function _mergeBelongsToMany($original, $assoc, $value, $include) {
if (isset($value['_ids']) && is_array($value['_ids'])) {
$hasIds = array_key_exists('_ids', $value);
if ($hasIds && is_array($value['_ids'])) {
return $this->_loadBelongsToMany($assoc, $value['_ids']);
}
if ($hasIds) {
return [];
}

if (!in_array('_joinData', $include) && !isset($include['_joinData'])) {
return $this->mergeMany($original, $value, $include);
Expand Down
55 changes: 55 additions & 0 deletions tests/TestCase/ORM/MarshallerTest.php
Expand Up @@ -477,7 +477,22 @@ public function testOneGenerateBelongsToManyEntitiesFromIds() {
];
$marshall = new Marshaller($this->articles);
$result = $marshall->one($data, ['Tags']);
$this->assertCount(0, $result->tags);

$data = [
'title' => 'Haz tags',
'body' => 'Some content here',
'tags' => ['_ids' => false]
];
$result = $marshall->one($data, ['Tags']);
$this->assertCount(0, $result->tags);

$data = [
'title' => 'Haz tags',
'body' => 'Some content here',
'tags' => ['_ids' => null]
];
$result = $marshall->one($data, ['Tags']);
$this->assertCount(0, $result->tags);

$data = [
Expand Down Expand Up @@ -725,6 +740,46 @@ public function testMergeBelongsToManyEntitiesFromIds() {
$this->assertInstanceOf('Cake\ORM\Entity', $result->tags[2]);
}

/**
* Tests that merging data to an entity containing belongsToMany and _ids
* will ignore empty values.
*
* @return void
*/
public function testMergeBelongsToManyEntitiesFromIdsEmptyValue() {
$entity = new Entity([
'title' => 'Haz tags',
'body' => 'Some content here',
'tags' => [
new Entity(['id' => 1, 'name' => 'Cake']),
new Entity(['id' => 2, 'name' => 'PHP'])
]
]);

$data = [
'title' => 'Haz moar tags',
'tags' => ['_ids' => '']
];
$entity->accessible('*', true);
$marshall = new Marshaller($this->articles);
$result = $marshall->merge($entity, $data, ['Tags']);
$this->assertCount(0, $result->tags);

$data = [
'title' => 'Haz moar tags',
'tags' => ['_ids' => false]
];
$result = $marshall->merge($entity, $data, ['Tags']);
$this->assertCount(0, $result->tags);

$data = [
'title' => 'Haz moar tags',
'tags' => ['_ids' => null]
];
$result = $marshall->merge($entity, $data, ['Tags']);
$this->assertCount(0, $result->tags);
}

/**
* Test merging the _joinData entity for belongstomany associations.
*
Expand Down

0 comments on commit 85aecb6

Please sign in to comment.