Hi,
After trying out this module for a project, I found that the deployment of content with field collections fails. I see the following error in the service response:
PDOException: SQLSTATE[HY000]: General error: 1366 Incorrect integer value: 'efb63753-06db-462f-98cd-165c462b8b14' for column 'field_grid_content_value'
I think this bug is related to this issue http://drupal.org/node/1541218.
The generated UUID of the field collection is not converted to a entity ID in the destination installation. I'm not sure if this is a bug for the UUID module or this module. What is a problem, is that the field collection data is not included in the JSON object sent to the rest service, or added to the deployment plan. Either solution could work, depending on the way the services module handles this.
There is an issue (with patch) for services support in the field collection module http://drupal.org/node/1180574. This issue is also related in the way deployment should deliver data to the webservice in a way supported by the module.
This will probably not be easy, but at least there is an issue to track the progress.
Comments
Comment #1
xadag commentedI had the same problem, i have the same response from my service
http://drupal.org/node/1820606
It use the uuid for entity id and try to save it in the database
Comment #2
ohthehugemanatee commentedI have the same problem. Actually, field_collection also has trouble with Services in general, but there's a nice patch in #11 at #1180574: Integration with Services which provides a perfectly reasonable implementation of services for field_collection. We could use that schema for Deploy, and between the two patches have the problem licked.
Here's the step-by-step:
1) Figure out if we're adding a field collection
2) load the related field collection entities into the queue to be deployed. We can probably rip behavior from related entity handling for this
3) structure the JSON output like the example from #1180574: Integration with Services
Comment #3
darrenmothersele commentedWould an alternative method be to implement the hooks in entity_dependency and then provide a field_collection_item service? I'll give this a shot and then report back.
Comment #4
darrenmothersele commentedThe entity dependency is already implemented by field_collection, so when deploying an entity with a field_collection it does already attempt to deploy the field_collection entities first. But deploy fails because there is no service for field_collection_items on the destination site.
I created a service resource to receive the field collection items, but it fails because the field collection items can't be created without a host entity, and they are being deployed first because of the entity_dependency.
I'm not sure what to do next? It seems like the entity containing the field collection would have to be deployed first, but this is not what happens with the implementation of hook_entity_dependencies().
Comment #5
darrenmothersele commentedI've managed to get field collections to deploy successfully, but only by overriding the FieldCollectionItemEntity class to prevent the default behaviour of throwing an exception if you try to save a field collection item without a host entity. This means that you can use the provided entity dependency to deploy field collection items first, and save them without the exception being thrown. Then, when the entity with the field collection field is deployed the items are already available to attach.
I'll post some example code once I get this tidied up.
Comment #6
teranex commented@darrenmothersele Would you care to share what you already have? I'm having the exact same problem so it would be nice if I could test your solution. thx!
Comment #7
seanbGreat to see there is progress so quickly! I'm also very curious what you made @darrenmothersele. If you could share this would be very helpfull!
Comment #8
darrenmothersele commentedHere's what I did to get Field collection items deploying. First override the default entity class with our own...
Then, in this custom field collection item controller class, override the default behaviour that prevents a Field Collection item from being saved without it's host entity. This is required because when deploying, you deploy the dependencies first (i.e. the field collection items before the host entity)...
Finally, on the receiving end I use hook_services_request_preprocess_alter() to convert the UUID of the field collection items in the field to a local ID of the field collection items. The entity dependency will have ensured that the field collection items have been deployed first...
It's not pretty (hard coding my node type, etc), but it works.
Comment #9
zach.bimson commentedThanks for this! looks really good.
Do you have an example json node that works with this?
Would help alot!
Comment #10
picardmyhero commentedComment #11
picardmyhero commentedAfter discussing this issue with Darren via email, here is a generic version of the last function of his solution...
Comment #12
picardmyhero commentedComment #13
picardmyhero commentedComment #14
zach.bimson commentedCould you please provide a generic JSON object that you'd pass to get this to work ?
Lets assume you have two fields in the collection called field_name and field_age..
Help would be much appreciated
Comment #15
jrobison commentedGuys, I tried the solution mentioned above and it does fix the error, however it doesn't seem to deploy the field collection items correctly.
What I am seeing is that the revision_id in the field_collection_item_revision table is actually an auto_increment field and thus the revision_id set everywhere else doesn't match the actual revision id that gets created. Because of this it would seem that the field collection items doesn't show up when editing / viewing the parent node in the destination environment.
I tried changing this:
to this:
However, this just seems to give me the revision id from the source table and not the destination table.
Any suggestions? Perhaps there's a way to call the next id on the the destination table to get this id?
Comment #16
jrobison commentedLooks like I misunderstood how the db_next_id works.
This fixed my issue:
Comment #17
mpgeek commentedIf anyone has tried this with fetch-only plans, i came up with a quick workaround that makes deployments via site install work. It is here #1997712: Alternative solution for deploying field collections via features (fetch only plans). I cannot speak to service/endpoint-based deployments, but the Features-based workflow only on install is functional. I'm trolling for input on a more general solution, and whether or not something should be patched.
Comment #18
timaholt commentedSo the code in #16 does seem to work in my testing, however it seems to be looping every possible field on each entity in the deploy regardless of whether or not that field is present in the entity. This leads to a lot of php warnings and notices in watchdog. I've tweaked the hook_services_request_preprocess_alter to replace the call to field_info_fields() with a call to field_info_instances. This ensures that only the fields that are attached to the entity are looped through.
Comment #19
dixon_So this should be implemented on the destination side, i.e. for
uuid_servicesmodule.Someone (I think it was @skwashd) added some stub code for this way back (see
uuid_services/resources/field_collection.resource.inc).Any takers on creating an actual patch for this?
Comment #20
mpgeek commentedWhat about fetch-only plans? It's my understanding that fetch only means no services at the endpoint, and Features does the "import" of content via
features-revert. Is there a way this can be implemented more generally so that both methods of deployment will work with field collection? I would be a taker on creating a patch, but I would be pulling for maximum coverage on all use cases.Comment #21
jamesharv commentedHere's a patch that I have managed to get working. I took a different approach to handling the revision_id. In
field_collection_field_uuid_presave()I just load all the field_collection_item entities that are stored in a field and grab their revision_ids.This works because the field_collection_item entities have already been saved, and will have been assigned a new revision_id at that time.
I also flag field_collection_item entities as having been universalized by setting
$entity->__uuid_universalized = TRUE. This flag is then checked in the new entity controller to ensure that I only bypass the normal controller logic for entities which have been universalized.Comment #22
jamesharv commentedComment #23
timaholt commentedCan you re-roll this patch? It doesn't apply to alpha4, alph5 or to latest dev.
Comment #24
jamesharv commentedHi @timaholt,
The patch was written against 7.x-1.x, and it does apply cleanly for me. It also applies cleanly for me against alpha5, see below:
Applied against 7.x-1.x branch:
Applied against 7.x-1.0-alpha5 tag:
Comment #25
timaholt commentedYou're right, what is odd here is that the patch applies cleanly with a git clone, but fails to apply in a drush make file (I do all my testing locally on a build using drush make). I suspect this is a permissions thing since the patch creates a directory. I will test this as soon as I can.
Comment #26
timaholt commentedSo i could never get this patch to work, but i did use this code in creating a field_collection_uuid module to put this in. It solves the original problem, but now I'm having issues with revisions on field collection items. Immediately after using this code, then creating a new revision on a node with a field_collection in it, I get a an SQL error asking for base.vuuid on the node table that the field collection was in. So then I created the field_collection_uuid module to put vuuid's on the field_collection_item_revision table, and that is works as expected. But trying to deploy a revision of a field_collection item shifted the base.vuuid error over to the field_collection_item_revision table:
PDOException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'base.vuuid' in 'where clause': 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, base.revision_id = revision.revision_id AS default_revision FROM {field_collection_item} base INNER JOIN {field_collection_item_revision} revision ON revision.revision_id = base.revision_id WHERE (base.item_id IN (:db_condition_placeholder_0)) AND (base.vuuid = :db_condition_placeholder_1) ;Has anyone come across this before? I've been going down a rabbit hole trying to figure this out...but so far without much luck.
Comment #27
timaholt commentedSo my above issue turned out to be with the deploy-revisions branch of deploy and trying to load a specific revision of an entity by it's vuuid in the entity_uuid_load function. Linked post here: https://drupal.org/node/2066401
Back to field collections, @jamesharv your code seems to work but I'm thinking perhaps we should move this all to a field_collection_uuid module and remove the load/presave functions from the UUID module. There is a similar module for Bean called Bean UUID that does the same thing. Ultimately it would be cleaner to have that code local to each contrib module, instead of trying to maintain it all inside the main UUID module.
Thoughts?
Comment #28
timaholt commented@jamesharv: I've put a new issue into the field_collection issue queue with a patch that provides all this as a submodule to field_collection called field_collection_uuid. Can you test this? I feel this is the better way to approach this, and combined with the issue on removing contrib support from UUID, it works perfectly in all my testing.
Field Collection UUID issue and patch: https://drupal.org/node/2075325
Removing contrib functions from UUID: https://drupal.org/node/2074599
Comment #29
robert castelo commentedFor anyone still looking for a solution - Field Collection Deploy module:
https://drupal.org/project/field_collection_deploy
Comment #30
miroslavbanov commentedThe problem is not only in deployment, and can easily be reproduced with a few simple lines of code.
I think we need a clear test to explain and an easy to reproduce steps.
To reproduce:
entity_uuid_load('node', array($uuid));I've created a very simple test - because of dependency has to be a separate (sub) module.
Comment #31
miroslavbanov commentedOops, here's the real patch
Comment #36
miroslavbanov commentedWell, I'm not sure how to create a test that requires another module. My steps to reproduce still are relevant though.
Comment #39
mrmikedewolf commentedThis is a reroll of 21 that will work with drush patchfile.
Comment #40
boobaaContrib module support was removed in #2074599: Remove all Contrib module functions from uuid.core.inc, plus reference where UUID support is for contrib modules, so this patch no longer applies. Rerolling it isn't straightforward, either, because of the same reason.
Comment #41
skwashd commentedMoving to UUID Extras.
Comment #42
boobaaMy goal was to be able to use Deploy to push nodes with Field Collection items on them to a target site which uses Services. After quite some struggling, I could get it work as expected. I collected the ideas from quite some places, including, but not limited to:
I'm using
The uuid.entity.inc file in UUID module needs to be patched because so many things call uuid_get_core_entity_info() directly in different places, and there is no other way to add the info which the patch adds (and the field_collection patch for uuid_extras relies on). If UUID folks really want to get rid of the contrib module support in UUID module, then I'd suggest adding a new hook, so other modules could alter the information before uuid_get_core_entity_info() returns it. But this is beyond this very issue (as it belongs to the UUID queue anyway).
Comment #43
boobaaComment #44
joao sausen commentedBoobaa, why does the patch applies to uuid_extras?
Also, confirming that #42 works!
Comment #45
harish.04 commentedHi Boobaa,
I have placed the "field_collection_uuid" module under UUID extras module and I have also applied the patch on UUID module as per #42 but still it does not support Field collections to be deployed.
Still I get the error "DeployServiceException: Service error: 404 Not found : Could not find resource field_collection_item."
Could you please help me with this issue.
Regards,
Harish M.
Comment #46
kt2ssh commented#42 it does works
Comment #47
boobaa@Joao Sausen in #44: the uuid_extras is the module to be patched since UUID folks decided to stop supporting non-core modules (see #40 and #41 above).
Comment #48
Adirael commentedMaybe it would work better as a submodule for field_collection, just an idea.
Anyway, patches on #42 worked great for me.