Hi,
I'm setting up an import where the bundle type is determined based on information in the incoming data and several extra fields are added for one of the content types (basically the incoming HTML code for the page is parsed using QueryPath and mapped to different fields, depending on the node type).
However, the field handlers for the extra fields are not being called for fields which are not a part of the default type (the one specified in the call to MigrateDestinationNode).
After debugging the code, I believe I found where the error occurs:
// from plugins/destinations/fields.inc
public function prepare($entity, stdClass $row) {
migrate_instrument_start('MigrateDestinationEntity->prepareFields');
// Look for Field API fields attached to this destination and handle appropriately
$migration = Migration::currentMigration();
$destination = $migration->getDestination();
$entity_type = $destination->getEntityType();
$bundle = $destination->getBundle(); // THIS ONLY GETS THE FIELDS FOR THE DEFAULT BUNDLE!!!
$instances = field_info_instances($entity_type, $bundle);
...
}
By changing $destination->getBundle(); to $entity->type, I was able to successfully execute the handlers. I'm not really familiar with how to make patches here yet, nor do I know if this is the best solution, but I thought it should be addressed in case anyone else tries to do this.
| Comment | File | Size | Author |
|---|---|---|---|
| #5 | migrate-bundle-extraction-1608400-5.patch | 2.14 KB | claudiu.cristea |
Comments
Comment #1
mikeryan$entity->type would work for nodes, but not in the general case for entities supporting bundles (e.g., vocabularies).
What you're attempting is unsupported - the static nature of a destination's bundle is a fundamental assumption of the design (e.g., in the migration detail pages, displaying the fields for the bundle). Supporting dynamic bundles in the general case would be quite a bit of work.
Comment #2
mikeryanComment #3
claudiu.cristeaI'm reopening this. I have the same scenario. I'm extending
MigrateDestinationNodeto allow migration to different kind of node types (bundles). Here's my destination:But this fails in
plugins/destinations/fields.inchere:and also in
->complete()because$destination->getBundle();returnsNULL.If we change
$bundle = $destination->getBundle();to:EDIT: Corrected the code.
and add a Drupal 6 backport function in
includes/d7.inc:This trick should allow us to handle multiple node types as a single destination. Note that this is nice handled in
plugins/destinations/node.inc:I would provide a patch for this but I want to know maintainer point of view.
Comment #4
claudiu.cristeaI'm taking this
Comment #5
claudiu.cristeaHere's a 6.x-2.x patch.
Comment #6
mikeryanThe maintainer, I must admit, is unenthused. In the current design, the bundle is an integral part of the identity of the migration - for one thing, it determines what fields are available for mapping. Trying to use one class for different destination bundles still feels hacky for me - is there a reason you can't have multiple migrations (derived from a common class, differing only on the destination construction and any bundle-specific field mappings)?
Comment #7
claudiu.cristeaMy case is not that important as the idea to keep
MigrateDestinationNodeas flexible as we can. In fact it was not my idea to extendMigrateDestinationNodein order to achieve a multi-node-type destination. Again, I'm posting a piece of code and the comment fromplugins/destinations/node.inc(line177) that talks itself thatMigrateDestinationNodewas designed to be extensible to a node-type agnostic class. Here it is:See the comment. It's the module author legacy that let us do that. In fact what I'm asking you is not to accept multi-node-type destination but only to get the the bundle value from entity instead of destination. What is wrong here? Why we wouldn't allow that?
Also, my patch was designed in a D7 style, using entity API to get the bundle. It's not hardcoded to nodes. The port to D7 it's straight -- I will provide a D7 patch too.
And, yes. My case is that I have a bunch of source objects stored in XML files (each record is a file). Destination are nodes having different types but same field instances. This is the client business model and it's senseless to argue here why the data structure has been designed in that way. Why should I write create migrations for each node-type if everything is the same except
$node->type? It makes no sense.Comment #8
frobI would like this feature. I am migrating paragraphs and it makes sense to have the bundle not pre-selected. I am going to see if that can happen in the bundle destination class. If it can then this wouldn't need to be in the migration core classes.