Problem description
I have workbench moderation installed and the default state for updates/new nodes is Draft/not published. In the node there is a field_collection with unlimited sub-field_collections which have a entity-reference field with autocomplete. When using the autocomplete in an unpublished node users without permissions to administer field_collections get a 403 error in a javascript pop-up.
Structure of the field_colelctions:
Node->field_collection->field_collection->autocomplete entityreference field
Technical description
1. When the node is saved, a new revision is created. The node module updates the {node} table to set the vid to the latest revision.
2. The field collection is saved in hook_field_update(). It checks if the host entity is the currently published version by using entity_revision_is_default(). This function checks the state in the {node} table and sees that it is the currently published version. The 'archived' property of the field_collections is set to FALSE and 'default_revision' is set to TRUE.
3. On its shutdown function workbench_moderation updates the {node} table to set the vid back to the version of the node that should be published.
4. When editing the draft a user tries to use autocomplete.
5. entityreference_autocomplete_callback_get_matches() gets called and checks for permissions on the entity the field belongs to (lower field_collection).
6. field_collection_item_access() gets called and tries to get the hostEntity to also check access on that.
8. FieldCollectionItemEntity->fetchHostDetails() calls $this->isInUse() to check if the field_collection is used by the currently active version. This returns FALSE on the upper field_collection (hostEntity should be the node) because here archived is set tho FALSE and default_revision is set to TRUE.
9. fetchHostDetails() queries only the published versions (INNER JOIN from {node} to {node_revision}, while stil trying to fetch the node by its revision-id.
10. No node entity is found, the upper field_collection has no hostEntity, entity_access('view', 'node', NULL) returns NULL, field_collection_item_access() returns FALSE.
Proposed solution
Change field_collection_field_update() to use workbench_moderation_node_live_load() to fetch the published version of the node instead of entity_load_single() as used in entity_revision_is_default(). I will upload a patch with this solution in it. If I have enough time I might even be able to create a test.
| Comment | File | Size | Author |
|---|---|---|---|
| #11 | field_collection-workbench_draft_revision_hostentity-2550061-11.patch | 4.02 KB | idebr |
Comments
Comment #2
Yaron Tal commentedAttached is the patch for the proposed solution.
Comment #3
Yaron Tal commentedAdded an update function to fix items that where broken.
Comment #4
rob c commentedFrom initial testing this all seems to be true, will test/debug some more tomorrow.
Comment #5
rohnjeynolds commentedGrateful to have found this issue, as I'm encountering the same problem, but not even on a nested field collection. My structure is node->field collection->entity reference autocomplete, where the field collection is configured to allow unlimited items.
The patch in #3 alleviates the 403 AJAX error but creates a condition where changes in new drafts of the field collection aren't reflected when previewing the host entity. The update function sets archived to 1 on affected nodes, but then field_collection_item table doesn't seem to update when new drafts of the node are saved. The only way I can get true relief is what feels like a dirty hack to the isInUse() method. Not eager to submit a patch because, like I said, it feels dirty, but was hoping for some feedback.
Comment #6
rohnjeynolds commentedI decided to roll a patch (UPDATE: Don't apply this patch!) based on a less dirty version of my dirty hack in #5. The premise I'm using to justify it is: If Workbench Moderation is enabled, the isInUse() method is less meaningful, especially when constructing the query to get the host entity info and determining which is the 'default' revision. For me, this solves both the 403 autocomplete error and doesn't impact the revisions behavior.
Comment #7
rohnjeynolds commentedThe patch in #6 is a fail. If you only check for Workbench Moderation in fetchHostDetails(), it turns out you'll get a 'host entity cannot be updated error' when saving the node. I'm back to checking for WM within isInUse(), which this new patch does. I'm only marginally confident that it's a proper solution, but it's still based on a sound premise/question: Does a method like isInUse() make sense, or mean the same thing, when Workbench Moderation is installed?
Comment #9
graper commentedI'm having the same issue but I am not using workbench moderation. I am using revisioning module and workflow. However the default archived flag being false is causing issues when the host entity is new and unpublished.
edit:
I found out that my problem was with node access not being set properly because workflow was not configured correctly.
Comment #10
rohnjeynolds commentedComment #11
idebr commentedReroll of #3 against the latest -dev
Comment #12
shenzhuxi commentedWorkbench_moderation 7.x-3.x + drafty seems can work with field_collection without patch #11.
I tried to use field_collection after applying patch https://www.drupal.org/node/2730265#comment-12080994. After both patches were applied, the published version will always show the latest draft while all the data seems be stored correctly.
Comment #13
siavash commentedI also needed patch: https://www.drupal.org/node/2634574#comment-10666236 to make sure editing drafts and saving as drafts works properly.