The support for Taxonomy Term Ref fields in Migrate module provides two subfields:
public function fields($type) {
return array(
'source_type' => t('Option: Set to \'tid\' when the value is a source ID'),
'create_term' => t('Option: Set to TRUE to create referenced terms when necessary')
);
}
These allow:
- use of the text label of an entity rather than its ID in the source column
- allow the migration to automatically create an entity when none is found for the given label text
We should implement these here too to be consistent. Furthermore, I imagine most migrations will have a text label rather than an ID, so doing the work once in the module rather than everyone having to write the same code in their own migration class makes sense.
Comments
Comment #1
joachim commentedNeeds #1391376: make buildEntityFieldQuery() public rather than protected so other modules can use it, because we need to be able to get the EFQ for the field's selection handler as only that knows about limiting by bundle.
Comment #2
joachim commentedWork in progress -- currently needs #1391376: make buildEntityFieldQuery() public rather than protected so other modules can use it, though that itself needs work.
Basically, this needs a reliable programmatic way of getting the allowed entities for a field, given an array of labels.
Comment #3
damien tournoud commentedHm. Why don't you use
->getReferencableEntities()directly?Comment #4
joachim commentedBecause it currently does a check_plain() on the labels - #1665818: Ampersands and other characters are not displayed correctly in <select> widgets
Also, I wasn't sure how it would handle a list of multiple values.
Comment #5
damien tournoud commentedYou don't have to use the label, just get the ID and build the labels separately if you need to.
Comment #6
joachim commentedThat seems a bit wasteful to me -- we'd be getting each label twice.
And the check_plain() shouldn't always be used anyway, for form elements that don't need it.
So IMO, getReferencableEntities() should return raw labels, and it's up to callers to decide whether to sanitize or not.
Comment #7
damien tournoud commentedNo,
EntityReference_SelectionHandler::getReferencableEntities()returns HTML, that's documented... the Views-based selection handler, for example, can return rich HTML labels.If you want plaintext, it's your job to downcase to HTML (that's what's missing in #1665818: Ampersands and other characters are not displayed correctly in <select> widgets)... but in that particular case you probably just want to call
entity_label()yourself, because you actually want the entity label, not whatever the selection widget wants to display to the user.Comment #8
joachim commentedOkay so in that case, could there be a version of getReferencableEntities() that's more API-ish, and returns just ids?
Comment #9
vlad.dancerThans @joachim. Here is rework of the joachim's patch based on
getReferencableEntities().Also added special fallback for taxonomy_term.
[TDB]: Add ignore_case option.
Comment #10
vlad.dancerBetter status.
Comment #11
vlad.dancerAdded support for
ignore_caseparameter.Comment #12
valentine94Looks nice to me, +1 to RTBC.
Comment #13
hypertext200This works fine out of the box, but documentation is necessary before push to repo.
Comment #14
vlad.dancerThanks for review, I'll take a look & try to add docs on the next week.
Comment #15
hypertext200Same patch rerolled with HTML encoded entity label support.
Comment #16
sardis commentedApplied patch, saved the day. RTBC!
Comment #17
vlad.dancer@Sardis, could you write/prepare a documentation about a new options for this destination plugin. See this documentation https://www.drupal.org/node/1224042
Comment #18
minoroffense commentedNeed API docs before it can be committed.
Comment #19
sardis commentedHere's the documentation for this feature, that, however, requires review as well:
Documentation link
I've also added
public function fields(), that should enlist sub-fields for entityreference fields in the Destination section within Migrate UI. That removes notices like:"field_my_entityreference:source_type" was mapped but not in the list of destination fields.
Also small CS fixes.
Comment #20
vlad.dancerComment #21
br0kenIt just doesn't work if the selection handler is the
\EntityReference_SelectionHandler_Views- an array lives in the$options['match']at\entityreference_plugin_display::query()anddb_like()against it produces a lot of warnings, becauseaddcslashes()can't convert an array to string. Fixing this you'll get in trouble with selection handler again - it'll return labels having an HTML and they will never match with values from source.The saddest thing is not that this is not working, but that it's impossible to fix this not adding breaking changes.
Also, the
create_entity_bundleargument is still not documentented.Comment #22
mpgeek commentedI can't speak to the use case in #21, but i think what was intended to be fixed was actually fixed by this patch.
After applying the patch at #19, i was able to migrate a new node that had an entity reference to an existing node with just the entity label (node title) in the source data (CSV if that is important).
Comment #23
br0kenI've been forced to refuse the idea of using the contributed (this one) field handler for entity references as it doesn't have some features I need. I'd suggest to not rely on this one and create yours to as much as possible meet the purposes of your migrations.
Comment #24
steven jones commentedI needed to add this functionality for a old D7 project, and needed to support a Views based selection handler.
Here's a patch that support that. Essentially:
create_entity_bundlesubfield.field_attach_validatefor all entity types, I'm not sure why it needed to be specifically taxonomy terms only.Hope it helps someone else!