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

joachim’s picture

Needs #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.

joachim’s picture

Status: Active » Needs work
StatusFileSize
new4.32 KB

Work 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.

damien tournoud’s picture

+      // Use the query for the selection handler for this field.
+      $handler = entityreference_get_selection_handler($field_info, $instance, $entity_type, $entity);
+      // WARNING: buildEntityFieldQuery relies on patch!
+      $query = $handler->buildEntityFieldQuery($values, 'IN');
+      $results = $query->execute();

Hm. Why don't you use ->getReferencableEntities() directly?

joachim’s picture

Because 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.

damien tournoud’s picture

You don't have to use the label, just get the ID and build the labels separately if you need to.

joachim’s picture

That 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.

damien tournoud’s picture

No, 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.

joachim’s picture

Okay so in that case, could there be a version of getReferencableEntities() that's more API-ish, and returns just ids?

vlad.dancer’s picture

Thans @joachim. Here is rework of the joachim's patch based on getReferencableEntities().
Also added special fallback for taxonomy_term.
[TDB]: Add ignore_case option.

vlad.dancer’s picture

Status: Needs work » Needs review

Better status.

vlad.dancer’s picture

Added support for ignore_case parameter.

valentine94’s picture

Looks nice to me, +1 to RTBC.

hypertext200’s picture

Status: Needs review » Reviewed & tested by the community

This works fine out of the box, but documentation is necessary before push to repo.

vlad.dancer’s picture

Thanks for review, I'll take a look & try to add docs on the next week.

hypertext200’s picture

Status: Reviewed & tested by the community » Needs review
StatusFileSize
new4.98 KB

Same patch rerolled with HTML encoded entity label support.

sardis’s picture

Status: Needs review » Reviewed & tested by the community

Applied patch, saved the day. RTBC!

vlad.dancer’s picture

@Sardis, could you write/prepare a documentation about a new options for this destination plugin. See this documentation https://www.drupal.org/node/1224042

minoroffense’s picture

Status: Reviewed & tested by the community » Needs work

Need API docs before it can be committed.

sardis’s picture

Status: Needs work » Needs review
StatusFileSize
new6.05 KB

Here'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.

vlad.dancer’s picture

Status: Needs review » Reviewed & tested by the community
br0ken’s picture

Status: Reviewed & tested by the community » Needs work

It 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() and db_like() against it produces a lot of warnings, because addcslashes() 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_bundle argument is still not documentented.

mpgeek’s picture

I 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).

br0ken’s picture

I'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.

steven jones’s picture

Status: Needs work » Needs review
StatusFileSize
new6.53 KB
new3.49 KB

I 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:

  • Instead of using the 'IN' operator which was a bit of a hack, loop over the input values, and use the previously supported '=' operator.
  • Switch to loading all matching entities and then asking the entity system for their labels. This is to avoid all the sillyness with un-escaping or having to fiddle around with stripping HTML. My views selection handler was adding tons of markup for example. Seems much nicer to fetch the clean entity label.
  • Document the create_entity_bundle subfield.
  • Always call field_attach_validate for all entity types, I'm not sure why it needed to be specifically taxonomy terms only.

Hope it helps someone else!