0

In D8, using Migrate Plus (8.x-4.0-beta3), i am pulling in xml records from an external, non-Drupal API. I have an unwieldy source URL that needs to be passed dynamically to the migrate_plus migration YML file. That doesn't seem possible, but I have read in comments that you can alter the source URL of a migration with hook_migrations_plugins_alter. However when i do something like below, the URL does not change.

function my_module_migration_plugins_alter(array &$migrations){

  foreach ($migrations as $id => $migration) {
    if ($migration['id'] == 'my_migrate_id'){
      unset($migrations['source']['urls']);
      $migration['source']['urls'] = 'http://example_api';
    }
  }
}

I realize I may need to override the source plugin; if this is true what method do i use to alter the source url?

1

If you don't want the overridden config to be saved to the database you can override it on the fly with ConfigFactoryOverrideInterface. I'm storing the file path in State API storage via a custom file upload form.

my_module.services.yml

services:
  my_module.overrider:
    class: \Drupal\my_module\MyModuleOverrides
    tags:
      - {name: config.factory.override, priority: 5}

src/MyModuleOverrides.php

<?php

namespace Drupal\my_module;

use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Config\ConfigFactoryOverrideInterface;
use Drupal\Core\Config\StorageInterface;

/**
 * Overrides migration configuration.
 */
class MyModuleOverrides implements ConfigFactoryOverrideInterface {

  /**
   * {@inheritdoc}
   */
  public function loadOverrides($names) {
    $overrides = array();
    $state = \Drupal::state();
    $overrides['migrate_plus.migration.my_migration']['source']['path'] = $state->get('my_module.my_migration_source_uri');
    return $overrides;
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheSuffix() {
    return 'MyModuleOverrider';
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheableMetadata($name) {
    return new CacheableMetadata();
  }

  /**
   * {@inheritdoc}
   */
  public function createConfigObject($name, $collection = StorageInterface::DEFAULT_COLLECTION) {
    return NULL;
  }

}
0
unset($migrations['source']['urls']);

You've got a typo here - it should be $migration, not $migrations.

Also note that plugin definitions are cached - you may need to do a cache rebuild after making changes to your alter hook for them to take effect.

  • Oh, but actually the unset line doesn't really matter, you're setting the right thing below. The cache rebuild comment stands. – Mike Ryan Jun 8 '18 at 15:50
  • Thank you for answering this. Good to know i am in the right direction. After running drush cr multiple times, however, the migration still pulls in the URL that is in the migration YML file... Any other suggestions? – kb_lib Jun 15 '18 at 20:24
  • I don't have any other ideas as to why it's not working for you - my next step would be, well, stepping through in a debugger. – Mike Ryan Jun 17 '18 at 15:11
0

I was actually running into the same issue until this morning. The source URLs are stored within the Config state (which is in the database).

I successfully altered the URL by doing the following:

function my_module_migration_plugins_alter(&$migrations) {
    foreach ($migrations as $id => $migration) {
        if ($migration['id'] == 'my_migrate_id'){
            $config = \Drupal::service('config.factory')->getEditable('migrate_plus.migration.'.$migration['id']);

            $config->set('source.urls', 'http://example_api');
            $config->save();
        }
    }
}
0

Your approach should work, as others have said you will need to clear cache. However there is a problem with your implementation. You're overriding the url on the $migration variable but never setting that back to the $migrations array.

Try this:

function my_module_migration_plugins_alter(array &$migrations){
  $migrations['my_migrate_id']['source']['urls'] = 'http://example_api';
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.