Closed (fixed)
Project:
Migrate
Version:
7.x-2.x-dev
Component:
Code
Priority:
Normal
Category:
Feature request
Assigned:
Reporter:
Created:
1 Jun 2011 at 08:04 UTC
Updated:
18 Jun 2011 at 22:41 UTC
Hi!
Is there a method where I can do something after a row has been created. Like post_row_creation(), similar to prepare_row()?
I am still working at a field_colletion handler and would like to call the field collection create methods. But this is only working if I can provide a parentEntityID which I don't have in prepare_row.
Regards
marcus
Comments
Comment #1
mikeryanDo you mean after an entity is created? When Migrate speaks of "row", it's talking about a row of source data retrieved from the source - prepareRow() is called after the data is retrieved but before any other handlers are called. Just before an entity is saved (e.g., node_save() is called) various prepare() handlers are called - first those registered to work with 'Entity', then those registered for the particular entity type ('node', 'user', etc.), then finally the migration's prepare() method. After the entity is saved, complete handlers are called.
I don't know how field_collection is constructed, but I would expect it to be similar to other field modules - look at plugins/destinations/fields.inc, or in migrate_extras look at date.inc, to see how they work.
Comment #2
marcusx commentedIf I speak from row I mean a row in the nodes table (because I am migrating nodes at the moment).
But let me clear things up.
Instead of "after row is created" I should say after a new destination node is created and therefore a node id to this node is existing.
Why is this important in this case.
A field collection is an entity itself. The field_collection_field in a node keeps only the reference to this entity_id.
You can think of it a little bit like a node reference field.
But with one important difference. The field_collection module takes care of keeping the integrity of the node reference. If I try to create an field_collection_item in code
I need to set theHostEntity. But I can't do it without the node id I don't have during migrate is preparing the row.
Maybe it is somehow possible to create the nodes first. And than running the migratione again as an update.
Is it possible to get the nodeid from the mapping tables via the API?
But all this wouldn't be neccessary if I could run an entity_create() after migrate has finished one "source row" of migration and the destination object has been created.
As field_collection module takes care of the integrity of the reference even a rollback wouldn't be a problem. If a node with a field collection in it is deleted, the referenced field_collection data is deleted automatically as well.
Comment #3
mikeryanSo you should be able to implement a complete handler. Take one of the existing field handlers as a model, replacing the prepare() function with a complete() function. Ahhh, but I see MigrateFieldsEntityHandler has a prepare() but not a complete(), it looks like we need to fill that hole for you...
Comment #4
marcusx commentedThat would be awesome.
So a complete() function would be called after the entiy is created, would than look like this...
Comment #5
mikeryanComment #6
marcusx commentedCan I copy the complete handler from the prepare handler in MigrateFieldsEntityHandler?
Like this:
Do I get it right that the prepare handler are called in migrate.module at this place:
But where could a complete handler be called? Or will this happen through some magic I can't find? As in destination.inc you already mention that it may be done.
Than maybe invoking the complete stuff is already done but I can't find it.
regards
marcus
Comment #7
marcusx commentedUuups! As I was writing this you grabbed the ticket.
Than I will make diff to figure out what has to be done after you commit something and try to learn it from there.
Thanks a lot!
Comment #8
mikeryanYes, it's true, migrate_field_handler_invoke_all needs to be extended to support complete as well.
It'll probably be a couple of days before I get to this.
Comment #9
mikeryanComment #10
mikeryanCommitted for D6 and D7.
Comment #11
marcusx commentedHi Mike!
Thanks! Works pretty well, but I have a problem with the $values in the complete handler. They are unset somewhere? Is this normal?
I return the values in the prepare function to have them available in the complete function. Is it correct to do it like that or will this call field API functions during prepare which will not work because of the invalid return value?
Comment #12
mikeryanDo not define prepare() unless you're using it to populate the field. The return value of prepare sets the value in the entity (e.g., the return value of the date field handler prepare() will populate $node->field_my_date) - what you're doing will just set that to the incoming value as is without putting things into the proper field form.
I can't explain why you wouldn't see $values set in the complete() handler - did you map anything to that field?