When adding or editing a field collection item that belongs to a node via the 'Embedded' method (i.e. the links that appear on the node view page) - if that node is under a revision control system (such as in my case 'Workbench moderation') - the changes made via these links are immediately updated, bypassing any revisioning or publishing workflows.

When the field collections are edited via the node edit form - the revisioning is respected (with this patch: #1807460: Field collection doesn't play nice with workbench moderation (patch)).

Many thanks,
Olly

Files: 
CommentFileSizeAuthor
#1 field_collection revisions.png47.97 KBbaronmunchowsen

Comments

Title:Embedded Actions don't respect Node Revisioning'In Content' add/edit actions don't respect Node Revisions
StatusFileSize
new47.97 KB

I'm updating with some more information.

1) Content type with a field collection field
2) Field collection field 'widget type' set to Embedded.
3) Add content using node/add form - creates first revision
4) Edit content using node/%/edit form - edit content title and field collection - check create a new revision - creates second revision
5) Look at node revisions - the revisions respect the changes to the field collections

--everything hunky-dory here--

6) NOW - edit the field collection field value from the node page (node/%) - see attached
7) Edit the field collection field value - save - the field collection field value has been updated BUT the node has not created a new revision.

The issue here is that this allows changes to be made to field collections that belong to nodes without respecting the rules that the node might be restricted by - for instance a module like workbench_moderation.

I can see that it could be very tricky to check and see what entity/bundle the field collection field belongs to and then see what steps need to be taken when saving that field. Perhaps it would be simpler to add a permission or option to turn 'off' the direct field collection edit paths:
field-collection///edit
field-collection//add/node/
when configuring the field - making the fields only editable via the node edit form (and therefore follow any revision control rules that node is under)...

Cheers,
Olly

Any progress on this issue? It seems like if we can create revisions from the node form, we should be able to do it more generally for all entity updates. I am willing to chip in some development time toward this, but am not too familiar with Entity API. Any suggestions on how we would approach this update?

Okay, here's what I've found...

In field_collection.pages.inc, the add/edit form calls this function:

<?php
function field_collection_item_form_submit($form, &$form_state) {
 
$field_collection_item = field_collection_item_form_submit_build_field_collection($form, $form_state);
 
$field_collection_item->save();
?>

Now we compare that to what's being called on node save:

<?php
function field_collection_field_presave($host_entity_type, $host_entity, $field, $instance, $langcode, &$items) {
  foreach (
$items as &$item) {
    if (isset(
$item['entity']) || !empty($host_entity->revision)) {
      if (
$entity = field_collection_field_get_entity($item)) {
        if (!empty(
$entity->is_new)) {
         
$entity->setHostEntity($host_entity_type, $host_entity, LANGUAGE_NONE, FALSE);
        }
        if (!empty(
$host_entity->revision)) {
         
$entity->revision = TRUE;
         
$is_default = entity_revision_is_default($host_entity_type, $host_entity);
          if (!isset(
$is_default) || $is_default) {
           
$entity->default_revision = TRUE;
           
$entity->archived = FALSE;
          }
        }
       
$entity->save(TRUE);
        ...
      }
    }
  }
}
?>

So I tried to copy some of this to the add/edit form. I added the following:

<?php
function field_collection_item_form_submit($form, &$form_state) {
 
$field_collection_item = field_collection_item_form_submit_build_field_collection($form, $form_state);
 
$field_collection_item->revision = TRUE;
 
$field_collection_item->default_revision = TRUE;
 
$field_collection_item->archived = FALSE;
 
$field_collection_item->save();
 
drupal_set_message(t('The changes have been saved.'));
 
$form_state['redirect'] = $field_collection_item->path();
}
?>

And this worked! Kinda... It did save the node and create a new revision for the field collection.

Unfortunately, I'm using the Revisioning module, which keeps different states of the node, and that's really throwing things off. If I have a node in a saved/draft state, and edit the node again, I lose the previous modifications. So while this approach kinda works, it's obviously not the "right way" to be doing this.

Any thoughts from those who are deeply entrenched with this module?