Commit ded2a962 authored by fago's avatar fago
Browse files

Issue #1776424: Removed field collections are never deleted.

parent b21ecfc0
......@@ -527,14 +527,16 @@ class FieldCollectionItemEntity extends Entity {
return;
}
$info = entity_get_info($this->hostEntityType());
if (empty($info['entity keys']['revision'])) {
if (empty($info['entity keys']['revision']) || !$this->hostEntity()) {
return $this->delete();
}
if (!$this->isDefaultRevision()) {
if (!$skip_host_update) {
// Just remove the item from the host, which cares about deleting the
// item (depending on whether the update creates a new revision).
$this->deleteHostEntityReference();
}
elseif (!$this->isDefaultRevision()) {
entity_revision_delete('field_collection_item', $this->revision_id);
if (!$skip_host_update) {
$this->deleteHostEntityReference();
}
}
// If deleting the default revision, take care!
else {
......@@ -555,11 +557,7 @@ class FieldCollectionItemEntity extends Entity {
->condition('item_id', $this->item_id)
->execute();
entity_get_controller('field_collection_item')->resetCache(array($this->item_id));
entity_revision_delete('field_collection_item', $this->revision_id);
if (!$skip_host_update) {
$this->deleteHostEntityReference();
}
}
}
}
......@@ -919,6 +917,40 @@ function field_collection_field_presave($host_entity_type, $host_entity, $field,
}
}
/**
* Implements hook_field_update().
*
* Care about removed field collection items.
*/
function field_collection_field_update($entity_type, $entity, $field, $instance, $langcode, &$items) {
$items_original = !empty($entity->original->{$field['field_name']}[$langcode]) ? $entity->original->{$field['field_name']}[$langcode] : array();
$original_by_id = array_flip(field_collection_field_item_to_ids($items_original));
foreach ($items as $item) {
unset($original_by_id[$item['value']]);
}
// If there are removed items, care about deleting the item entities.
if ($original_by_id) {
$ids = array_flip($original_by_id);
// If we are creating a new revision, the old-items should be kept but get
// marked as archived now.
if (!empty($entity->revision)) {
db_update('field_collection_item')
->fields(array('archived' => 1))
->condition('item_id', $ids, 'IN')
->execute();
}
else {
// Delete unused field collection items now.
foreach (field_collection_item_load_multiple($ids) as $item) {
$item->deleteRevision(TRUE);
}
}
}
}
/**
* Implements hook_field_delete().
*/
......
......@@ -45,15 +45,23 @@ class FieldCollectionBasicTestCase extends DrupalWebTestCase {
}
/**
* Tests CRUD.
* Helper for creating a new node with a field collection item.
*/
function testCRUD() {
protected function createNodeWithFieldCollection() {
$node = $this->drupalCreateNode(array('type' => 'article'));
// Manually create a field_collection.
$entity = entity_create('field_collection_item', array('field_name' => $this->field_name));
$entity->setHostEntity('node', $node);
$entity->save();
return array($node, $entity);
}
/**
* Tests CRUD.
*/
function testCRUD() {
list ($node, $entity) = $this->createNodeWithFieldCollection();
$node = node_load($node->nid, NULL, TRUE);
$this->assertEqual($entity->item_id, $node->{$this->field_name}[LANGUAGE_NONE][0]['value'], 'A field_collection has been successfully created and referenced.');
$this->assertEqual($entity->revision_id, $node->{$this->field_name}[LANGUAGE_NONE][0]['revision_id'], 'A field_collection has been successfully created and referenced.');
......@@ -104,10 +112,7 @@ class FieldCollectionBasicTestCase extends DrupalWebTestCase {
$this->assertTrue(count($node->{$this->field_name}[LANGUAGE_NONE]) == 1 && !empty($node->{$this->field_name}[LANGUAGE_NONE][0]['value']) && !empty($node->{$this->field_name}[LANGUAGE_NONE][0]['revision_id']), 'Link has been established.');
// Test Revisions.
$node = $this->drupalCreateNode(array('type' => 'article'));
$item = entity_create('field_collection_item', array('field_name' => $this->field_name));
$item->setHostEntity('node', $node);
$item->save();
list ($node, $item) = $this->createNodeWithFieldCollection();
// Test saving a new revision of a node.
$node->revision = TRUE;
......@@ -148,12 +153,7 @@ class FieldCollectionBasicTestCase extends DrupalWebTestCase {
// Test having archived field collections, i.e. collections referenced only
// in non-default revisions.
$node = $this->drupalCreateNode(array('type' => 'article'));
// Manually create a field_collection.
$item = entity_create('field_collection_item', array('field_name' => $this->field_name));
$item->setHostEntity('node', $node);
$item->save();
list ($node, $item) = $this->createNodeWithFieldCollection();
// Create two revisions.
$node_vid = $node->vid;
$node->revision = TRUE;
......@@ -192,6 +192,24 @@ class FieldCollectionBasicTestCase extends DrupalWebTestCase {
// collection item as it contains its last revision.
node_revision_delete($node_vid);
$this->assertFalse(field_collection_item_load($item->item_id), 'Archived field collection deleted when last revision deleted.');
// Test that removing a field-collection item also deletes it.
list ($node, $item) = $this->createNodeWithFieldCollection();
$node->{$this->field_name}[LANGUAGE_NONE] = array();
$node->revision = FALSE;
node_save($node);
$this->assertFalse(field_collection_item_load($item->item_id), 'Removed field collection item has been deleted.');
// Test removing a field-collection item while creating a new host revision.
list ($node, $item) = $this->createNodeWithFieldCollection();
$node->{$this->field_name}[LANGUAGE_NONE] = array();
$node->revision = TRUE;
node_save($node);
// Item should not be deleted but archived now.
$item = field_collection_item_load($item->item_id);
$this->assertTrue($item, 'Removed field collection item still exists.');
$this->assertTrue($item->archived, 'Removed field collection item is archived.');
}
/**
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment