function field_collection_field_update in Field collection 7
Implements hook_field_update().
Care about removed field collection items.
Support saving field collection items in
$item['entity'];
. This may be used to seamlessly create field collection items during host-entity creation or to save changes to the host entity and its collections at once.
File
- ./
field_collection.module, line 558 - Module implementing field collection field type.
Code
function field_collection_field_update($host_entity_type, $host_entity, $field, $instance, $langcode, &$items) {
// When entity language is changed field values are moved to the new language
// and old values are marked as removed. We need to avoid processing them in
// this case.
$entity_langcode = field_collection_entity_language($host_entity_type, $host_entity);
$original = isset($host_entity->original) ? $host_entity->original : $host_entity;
$original_langcode = field_collection_entity_language($host_entity_type, $original);
$langcode = $langcode == $original_langcode ? $entity_langcode : $langcode;
$top_host = $host_entity;
while (method_exists($top_host, 'hostEntity')) {
$top_host = $top_host
->hostEntity();
}
// Prevent workbench moderation from deleting field collections or paragraphs
// on node_save() during workbench_moderation_store(), when
// $host_entity->revision == 0.
if (!empty($top_host->workbench_moderation['updating_live_revision'])) {
return;
}
// Don't modify the field collections if using drafty and this is not a
// draft revision.
if (module_exists('drafty') && empty($top_host->is_draft_revision)) {
return;
}
// Load items from the original entity.
$items_original = !empty($original->{$field['field_name']}[$langcode]) ? $original->{$field['field_name']}[$langcode] : array();
$original_by_id = array_flip(field_collection_field_item_to_ids($items_original));
foreach ($items as $delta => &$item) {
// In case the entity has been changed / created, save it and set the id.
// If the host entity creates a new revision, save new item-revisions as
// well.
if (!empty($host_entity->revision) || isset($item['entity'])) {
if ($entity = field_collection_field_get_entity($item)) {
// If the host entity is saved as new revision, do the same for the item.
if (!empty($host_entity->revision) || !empty($host_entity->is_new_revision)) {
$entity->revision = TRUE;
// Without this cache clear entity_revision_is_default will
// incorrectly return false here when creating a new published
// revision.
if (!isset($cleared_host_entity_cache)) {
list($entity_id) = entity_extract_ids($host_entity_type, $host_entity);
entity_get_controller($host_entity_type)
->resetCache(array(
$entity_id,
));
$cleared_host_entity_cache = TRUE;
}
$is_default = entity_revision_is_default($host_entity_type, $host_entity);
// If an entity type does not support saving non-default entities,
// assume it will be saved as default.
if (!isset($is_default) || $is_default) {
$entity->default_revision = TRUE;
$entity->archived = FALSE;
}
else {
$entity->default_revision = FALSE;
}
}
if (!empty($entity->is_new)) {
$entity
->setHostEntity($host_entity_type, $host_entity, $langcode, FALSE);
}
else {
$entity
->updateHostEntity($host_entity, $host_entity_type);
}
$entity
->save(TRUE);
$item = array(
'value' => $entity->item_id,
'revision_id' => $entity->revision_id,
);
if (module_exists('pathauto')) {
module_load_include('inc', 'field_collection', 'field_collection.pathauto');
field_collection_pathauto_create_alias($host_entity, $entity, 'update');
}
}
}
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($host_entity->revision)) {
db_update('field_collection_item')
->fields(array(
'archived' => 1,
))
->condition('item_id', $ids, 'IN')
->execute();
// Let other modules know about the archived items.
foreach (field_collection_item_load_multiple($ids) as $un_item) {
entity_get_controller('field_collection_item')
->invoke('archive', $un_item);
entity_get_controller('field_collection_item')
->resetCache(array(
$un_item->item_id,
));
}
}
else {
// Load items from the original entity from all languages checking which
// are the unused items.
$current_items = array();
$languages = language_list();
foreach ($languages as $langcode_value) {
$current_items += !empty($host_entity->{$field['field_name']}[$langcode_value->language]) ? $host_entity->{$field['field_name']}[$langcode_value->language] : array();
$current_by_id = field_collection_field_item_to_ids($current_items);
}
$items_to_remove = array_diff($ids, $current_by_id);
// Delete unused field collection items now.
foreach (field_collection_item_load_multiple($items_to_remove) as $un_item) {
$un_item
->updateHostEntity($host_entity, $host_entity_type);
$un_item
->deleteRevision(TRUE);
if (module_exists('pathauto')) {
pathauto_entity_path_delete_all('field_collection_item', $un_item);
}
}
}
}
}