Comments

alexweber’s picture

Status: Active » Needs review
StatusFileSize
new1.93 KB

Initial migrate field handler implementation attached.

There's some room for improvement such as making it behave like legit term reference handler (using SourceMigration to map tids) but either way its a solid start IMO.

alexweber’s picture

Fixed a minor typo in the hook implementation

alexweber’s picture

Ok so turns out that the above implementation actually works very well with single value fields however it falls short with fields that accept multiple values.

The reasoning is simple: We're using field mapper arguments for the level and the arguments are bound to the mapping in general and can't (that I know of) be specified dynamically. I even tried using ->separator(',') on both the primary value and arguments and passing a comma-separated string but the argument doesn't know how to deal with multiple values and implementing that turned out to be kinda messy.

So, plan B is actually even more elegant and I can confirm that it works like a charm on multi-value fields: use a subfield.

So here's a new patch that refactors the field handler implementation to use subfields instead of arguments for the term level.

mh86’s picture

Thanks for the patch, Alex!
I haven't tested it yet, and I'm not familiar with the internals of migrate field handlers, but this handler might soon be a topic for the Recruiter.
Do you have a code sample how the handler is used in migration scripts (e.g. in drop jobs)?

alexweber’s picture

@mh86, why yes I do and thanks for asking! )

Lines 43-46: http://drupalcode.org/project/drop_jobs.git/blob/refs/heads/7.x-1.x:/modules/custom/drop_jobs_demo/drop_jobs_demo_candidates_skills.migrate.inc

BTW, the only reason I had to manually find the TID in prepareRow() is because the "skill" vocab terms were imported using Taxonomy CSV and not migrated using migrate, if that had been the case I could have just as easily gone with something like this:

$this->addFieldMapping('field_candidate_skills_level:level', 'level')
  ->separator(',');
$this->addFieldMapping('field_candidate_skills_level', 'skill')
  ->separator(',')
  ->sourceMigration('TermMigrationName')
  ->arguments(array('source_type' => 'tid'));

I've successfully tested this handler with both single and multi-value Term Level fields and it seems to work 100%.

PS - In order to get these exported via CSV I had to create an extra field formatter for term_level fields to export in a CSV-friendly format (simple and particular enough use case that I didn't bother with a patch, let me know if this is interesting though)

/**
 * Implements hook_field_formatter_info().
 *
 * Adds some extra display formatters for Term Level fields so that we can
 * easily export the data to CSV.
 */
function drop_jobs_dev_field_formatter_info() {
  $info = array();

  $info['term_level_export'] = array(
    'label' => t('CSV Export'),
    'description' => t('Formats the data to be easily exportable via CSV'),
    'field types' => array('term_level'),
    'settings' => array(),
  );

  return $info;
}

/**
 * Implements hook_field_formatter_view().
 */
function drop_jobs_dev_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $term_levels = array();
  foreach ($items as $delta => $item) {
    $term_levels[$item['tid']] = $item['level'];
  }
  $terms = taxonomy_term_load_multiple(array_keys($term_levels));

  $element = array();
  if ($display['type'] == 'term_level_export') {
    foreach ($term_levels as $tid => $level_key) {
      if (isset($terms[$tid])) {
        $term = $terms[$tid];
        $element[$tid] = array('#markup' => check_plain($term->name) . '|' . check_plain($level_key));
      }
    }

    return $element;
  }
}
alexweber’s picture

Oops, the previous patch removed the newline at the end of term_level.info and caused some weird errors when installing a distribution that requires term_level.

This new patch just makes sure that the newline at the end of that file remains intact.

alexweber’s picture

I'm actually getting a bit embarrassed by the repeated patch posting that's going on over here. The patches in #3 and #6 apply cleanly (using git apply) and work fine locally but for whatever reason the Drupal.org build script is having trouble building my distribution with this patch. I'm using drush make with --working-copy to test it and I've read that sometimes it can cause patches to fail.

Regardless, here's my last-ditch attempt. I've started from a clean slate and generated a clean patch by staging the changes and doing git diff --cached, which I've now learnt is the preferred method to include new files in a patch.

Hope this works and if it doesn't, I promise I'll find another issue queue to flood.

Thank you for your patience!

mh86’s picture

Status: Needs review » Fixed

Hi Alex,

thanks for your work, I've just committed your patch!
I haven't tried it with a concrete migrate example yet, but the code basically looks good. If there are any issues, we can handle it in follow-ups.

No idea why the patch didn't apply with drush, but we've seen such problems in the Recruiter as well.

alexweber’s picture

Awesome, thanks!!!

mh86’s picture

Hey Alex,

I've added a small extension to the migration handler, so that term names can be passed as well (we're using it in the Recruiter). The code is more or less copied from the default term field handler, and I hope it does not destroy your existing migrationa. If so you might have to change the source_type in the arguments.

Diff: http://drupalcode.org/project/term_level.git/commitdiff/1abc4cf

alexweber’s picture

Hey Matthias, no worries, thanks for the heads up!

This is a nice improvement, I'll update my migrations to use it! :)

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.