This patch contains a new submodule called field_collection_uuid.
This submodule brings "proper" UUID support (both uuid and vuuid for revisions). It also provides various helper functions in order to get field collections and their revisions deploying properly using deploy and UUID.
Comments
Comment #1
mpv commentedThanks! It worked for me. This together with https://drupal.org/node/1670740#comment-7647431 allowed me to export and reimport nodes with field_collections using node export.
Comment #2
mpv commentedI needed to use this in a server with php 5.2 and it turns out that anonymous functions are only supported in php since 5.3. Here's an updated patch that replaces the array map in line 44 of field_collection_uuid.module with a foreach loop.
Comment #3
gilgabar commentedThis is great so far, but there are some issues. Here is an updated patch to address some of them.
- General cleanup to address coding standards issues.
- Remove the __uuid_universalized property on hook_entity_uuid_load(). It doesn't appear to do anything.
- Remove the constructor from UUIDFieldCollectionItemEntity. Its just calling the parent constructor, so there isn't really a need for it.
- Remove $this->revision = TRUE from UUIDFieldCollectionItemEntity::save(). It was forcing every save (when the hostEntity is absent) to create a new revision which should not be necessary. And without it field collection items with revisions appear to deploy correctly anyway (in my very simple testing anyway). Revision support should be tested more thoroughly by someone who actually uses revisions.
Also there are some PHP notices in the log after deploying field collections with this patch. The following sound similar to #1774914: Notice: Undefined property: CommerceOption::$option_id in drupal_write_record() includes/common.inc.. It isn't clear why these are happening. It looks like property_exists() is returning TRUE for properties that don't exist. This doesn't happen in a normal field collection save, so it should be investigated more:
- Notice: Undefined property: UUIDFieldCollectionItemEntity::$item_id in drupal_write_record() (line 7049 of /includes/common.inc).
- Notice: Undefined property: UUIDFieldCollectionItemEntity::$revision_id in drupal_write_record() (line 7049 of /includes/common.inc).
And these appear to be due to this issue #1780646: entity_access() fails to check node type specific create access, so probably not relevant to this patch.
- Notice: Undefined property: stdClass::$nid in entity_metadata_no_hook_node_access()
- Notice: Undefined property: stdClass::$vid in entity_metadata_no_hook_node_access()
- Notice: Trying to get property of non-object in entity_metadata_no_hook_node_access()
- Notice: Undefined property: stdClass::$nid in node_access()
I would also suggest that it would be a good idea to move the field collection services code from UUID into this submodule as well. This seems like a much more appropriate place for it.
Comment #4
timaholt commentedI will retest this latest patch since I am using revisions on the field collections and see where we net out. I haven't seen the notices you are seeing, but it sounds like one of the entities isn't being loaded successfully for you?
Comment #5
timaholt commentedsorry wrong place!
Comment #6
jrbeemanThe patch in #3 appears to not work properly with the deployment of subsequent changes (revisions) to field collection items. I haven't dug into why yet, but my guess is it's the change in field_collection_field_uuid_presave()
*edit*
Just noting that the original patch works as expected.
Comment #7
gilgabar commentedThanks for testing that jrbeeman. It is almost certainly the $this->revision = TRUE from UUIDFieldCollectionItemEntity::save() in the original patch that allows revisions to function correctly on subsequent changes. But that seems like an inappropriate, hacky solution. It essentially just forces every save to be a new revision regardless of whether or not it is actually necessary to have a new revision.
So the patch needs work, but it needs a better solution than the one used in the original patch.
Comment #8
gilgabar commentedComment #9
timaholt commentedSo yeah this needs some rethinking if you don't want new revisions on your field_collection items.
I guess the possible scenarios are:
- Initial creation of the field_collection item (based on Jeff's comments it appears not to matter what $this->revision is set to since initial creation worked with either version of the patch)
- Update of the default_revision of the field_collection_item (in the case you'd want $this->revision = FALSE)
- Creation of a new revision of the field_collection item (where you need $this->revision = TRUE)
This leads me to think that we'd need to do a couple things:
- make sure that the default_revision property is there on field_collection entities (it's not currently)
- perhaps call entity_revision_is_default() in order to check if we want to update the default revision (where we'd set $this->revision = FALSE), although it would need a lot of testing to make sure that it returned the right result depending on what we wanted to do
- for uuid and node revisions themselves, we are essentially checking if the content type has "create new revision" as default, and then flipping the flag either way. it's not ideal but it does work. we may have to fallback to a check like this if the field collections parent node is creating new revisions by default
Thoughts?
Comment #10
gilgabar commentedI'm not especially familiar with the details of the revision system, particularly as it relates to field collections, so I will need to do some research before I can offer any sort of informed opinion on the right way to handle this.
My current (probably naive) understanding is that field collection revisions get their own uuid, so that when we deploy an update for a field collection with a new revision, the receiving instance of Drupal should be able to see that the uuid of the revision on the field collection entity is different from the uuid of the current revision and therefore it should create a new revision with that new uuid. It doesn't seem like it should require jumping through a bunch of hoops. I would expect most (or all) of that to just work via the normal machinations of the UUID and field collection modules, but as it does not, I suspect my understanding is currently flawed. If anyone has any insights into that it would be very helpful.
Comment #11
ohthehugemanatee commentedThanks for the great work here. The patch applied cleanly for me, but using Deploy module I'm still getting errors that the field collection can't be saved without a Host Entity.
That issue was originally addressed in https://drupal.org/node/1817956 , which spawned this ticket and improved approach... so I expected it wouldn't be a problem here. Is there another patch I need to apply to get correct dependency handling?
Comment #12
timaholt commentedSo there is one more patch I apply to make this work here:
https://drupal.org/files/uuid_services_field_collection_revisions.patch
This is a hack at the moment, but the access callback for field collections returns false when you are trying to save it on it's own. This needs to be changed in field_collection somewhere, but this quick and dirty patch does the trick.
Comment #13
thtas commentedWhen i try to install this patch and enable field_collection_uuid i get an error because field_collection_entity_uuid_load() is already declared in the uuid module.
How should field collection uuid be handled - with this patch or with the uuid module?
EDIT
Nevermind i just noticed the related issue on the site there.
Comment #14
ciss commentedComment #15
ciss commented(Sorry, got the wrong issue id.)
Comment #16
jmking commentedThis is the closest, workable approach I've found so far if you're looking to deploy field collections through services. The patch in the referenced thread above (#2309103) suggests a patch which removes all contrib support from uuid (including services support, but doesn't put it back anywhere). Essentially there doesn't seem to be a complete, working solution for deploying field collections via services yet.
That said, the patch in comment #3 works if you apply the attached patch for uuid which removes the conflicting implementation for field_collection only. This is not a long-term solution, but just a workaround to make this patch work in the meantime. This is also why I didn't post it in the uuid thread - it is not of use to anyone but those intending to use the patch in comment #3.
Hopefully this helps someone who needs a stopgap solution for deploying field collections via services while the approach in #2309103 gets fully fleshed out and adopted by all contrib modules currently supported by uuid.
If you don't need to deploy via services and you're doing a fetch-only deployment plan, the patches in the other thread work.
Comment #17
joseph.olstadpatch 3 seems to work well on mysql and postgres
however in mssql using the latest sqlsrv drivers we're getting this error:
PDOException: SQLSTATE[22018]: [Microsoft][ODBC Driver 11 for SQL Server][SQL Server]Conversion failed when converting the varchar value '97a7296d-ed89-4437-b4f2-032d82f53469' to data type int.: SELECT revision.[revision_id] AS [revision_id], revision.[vuuid] AS [vuuid], base.[item_id] AS [item_id], base.[field_name] AS [field_name], base.[archived] AS [archived], base.[uuid] AS [uuid], cross_default_revision.cross_sqlsrv AS default_revision FROM field_collection_item base INNER JOIN field_collection_item_revision revision ON revision.revision_id = base.revision_id CROSS APPLY (SELECT CASE WHEN base.revision_id = revision.revision_id THEN 1 ELSE 0 END cross_sqlsrv) cross_default_revision WHERE ( ([base].[item_id] IN (:db_condition_placeholder_0, :db_condition_placeholder_1)) ); Array ( [:db_condition_placeholder_0] => 7 [:db_condition_placeholder_1] => 97a7296d-ed89-4437-b4f2-032d82f53469 ) in EntityAPIController->query() (line 187 of profiles\wetkit\modules\contrib\entity\includes\entity.controller.inc).
we're working on a solution at this moment.
Comment #18
sylus commentedI spend a lot of time between this issue and the related one and couldn't get field_collections to properly deploy with services. Eventually I got it working with a combination of patches and thought I would document them here. One thing I should mention is I had to resort to parts of the patch in #2 because the patch in #3 wouldn't deploy and was either getting error messages about the revision_id or when removed the UUIDFieldCollectionItemEntity file errors such as: "Unable to create a field collection item without a given host entity". I kept some of the improvements from the patch in #3 but kept the revision logic + UUIDFieldCollectionItemEntity from #2. Aside from that I am using the following:
As well as deploy 2.0-alpha3 and services 3.12 with a few additional patches. I have created two patches that apply to field_collection. An updated patch for field_collection_uuid related to what was mentioned above and a new patch which creates a field_collection_uuid_services module that has to be enabled on the destination site so resources under services can be configured for field collection. This is due to the field collection services integration being removed from the uuid module.
Everything then seemed to work as supposed to.
Comment #19
skwashd commentedMarking as needs review so someone can look at @sylus' patches above.
Comment #20
joseph.olstadSylus patches are working for us.
RTBC+1
Comment #21
dillix commented+1 for RTBC
Comment #22
jmuzz commentedSo for this to work it requires UUID to be patched with a special case to handle field collections.
If I understand correctly, the problem happens when an access check happens on a field collection item that has been created but not assigned to a host entity yet. Is there a reason we can't / shouldn't support this?
Comment #23
capogeannis commented@sylus' 2 patches here solve my current issue - deploy of nodes with field collections working great now. glad to have found this in a pinch.
Comment #24
caspervoogt commented@sylus' 2 patches in #18 worked for me in conjunction with the Deploy module ... like a charm. RTBC?
Comment #25
boobaaThere's an issue in the queue of the new UUID Extras module which is related to this: #1817956-42: Field collection support. TL;DR: Field Collection itself is not really affected, but UUID and UUID Extras needs patching. Some extra work might be needed for the revision-related part.
Comment #26
mallezieJust noting here. When using this module, we encountered a problem when cloning / translating nodes with field collections.
The field collections get the same UUID as the ones they're coming from. This causes issues on deployment where the target site get's different field collection assigned.
As a quick solution now, i added the uuid and vuuid reset in field_collection_field_insert, but this should probably be done better in field_collection_field_uuid_presave.