0

I have a drupal migration that also uses migrate plus from a feed URL that can be queried. For example the migration can work for a single response from the feed at

source:
  plugin: url
  data_fetcher_plugin: http    
  data_parser_plugin: xml   
  urls: http://myfeed.com/newsfeed/get.php?id=123456

I would like to migrate content at 123456 and then 123457, then 123458. How could this be done?

0

If you only have to migrate to this 3 ids, just create 3 different migrations for each URL.

If the IDs are dinamic I will copy&paste my own solution:

To solve this I had to create a source plugin that for each row calls a new data parse plugin with the URL for this row.

Here is the plugin:

/**
*
* @MigrateSource(
*   id = "url_per_row"
* )
*/
class UrlPerRow extends Url {

protected $dataNewParserPlugin;

  /**
   * {@inheritdoc}
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration) {
    parent::__construct($configuration, $plugin_id, $plugin_definition, $migration);
  }

  /**
   * {@inheritdoc}
   */
  public function prepareRow(Row $row) {
    $prepare_row = parent::prepareRow($row);

    if (!$row->getIdMap() || $row->needsUpdate() || $this->aboveHighwater($row) || $this->rowChanged($row)) {
      $item_info_settings = $row->getSourceProperty('item_info');
      if (!empty($item_info_settings)) {
        $this->getItemData($row, $item_info_settings);
      }
    }

    return $prepare_row;
  }

  protected function getItemData(Row &$row, $settings) {
    $new_url = str_replace($settings['token'], $row->getSourceProperty($settings['token_replace']), $settings['url']);

    $this->getNewDataParserPlugin($new_url, $settings['item_selector'],     $row->getSource());
    $this->dataNewParserPlugin->rewind();
    $xml_data = $this->dataNewParserPlugin->current();
    if (!empty($xml_data)) {
      $fields = $row->getSourceProperty('fields');
      foreach ($fields as $field) {
        if (!empty($field['item_info']) && !empty($xml_data[$field['name']])) {
          $row->setSourceProperty($field['name'], $xml_data[$field['name']]);
        }
      }
    }
  }

  protected function getNewDataParserPlugin($url, $item_selector, $settings) {
    $settings['urls'] = [$url];
    $settings['item_selector'] = $item_selector;

    $this->dataNewParserPlugin = \Drupal::service('plugin.manager.migrate_plus.data_parser')
      ->createInstance($settings['data_parser_plugin'], $settings);

    return $this->dataNewParserPlugin;
  }

}

Then I put some info in the migration .yml definition:

source:
  plugin: url_per_row
  data_fetcher_plugin: http
  headers:
    Accept: application/xml
  data_parser_plugin: simple_xml
  urls: https://myws.com
  item_selector: /ResultWeb/data
  item_info:
    url: https://myws.com/[id]
    token: '[id]'
    token_replace: id
    item_selector: /ResultWeb/data

Notice that the id from token_replace is a field with name id. You can use other field.

Also, for every field where is needt to rereive information from the specified URL I put a item_info: true element.

-
  name: myfield
  label: 'My Field'
  selector: fields/field/my
  item_info: true
|improve this answer|||||
0

You should be able to list any URLs that should be fetched:

source:
  plugin: url
  data_fetcher_plugin: http    
  data_parser_plugin: xml   
  urls:
    - http://myfeed.com/newsfeed/get.php?id=123456
    - http://myfeed.com/newsfeed/get.php?id=123457
    - http://myfeed.com/newsfeed/get.php?id=123458

The Url plugin in migrate_plus converts single url values into an array by default: https://git.drupalcode.org/project/migrate_plus/blob/HEAD/src/Plugin/migrate/source/Url.php#L34

|improve this answer|||||

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.