MigrateStub.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. <?php
  2. namespace Drupal\migrate;
  3. use Drupal\Component\Plugin\Exception\PluginNotFoundException;
  4. use Drupal\migrate\Plugin\MigrateIdMapInterface;
  5. use Drupal\migrate\Plugin\MigrationInterface;
  6. use Drupal\migrate\Plugin\MigrationPluginManagerInterface;
  7. /**
  8. * Provides the migrate stubbing service.
  9. */
  10. class MigrateStub implements MigrateStubInterface {
  11. /**
  12. * The migration plugin manager.
  13. *
  14. * @var \Drupal\migrate\Plugin\MigrationPluginManagerInterface
  15. */
  16. protected $migrationPluginManager;
  17. /**
  18. * Constructs a MigrationStub object.
  19. *
  20. * @param \Drupal\migrate\Plugin\MigrationPluginManagerInterface $migration_plugin_manager
  21. * The migration plugin manager.
  22. */
  23. public function __construct(MigrationPluginManagerInterface $migration_plugin_manager) {
  24. $this->migrationPluginManager = $migration_plugin_manager;
  25. }
  26. /**
  27. * Creates a stub.
  28. *
  29. * @param string $migration_id
  30. * The migration to stub.
  31. * @param array $source_ids
  32. * An array of source ids.
  33. * @param array $default_values
  34. * (optional) An array of default values to add to the stub.
  35. * @param bool $key_by_destination_ids
  36. * (optional) NULL or TRUE to force indexing of the return array by
  37. * destination id keys (default), or FALSE to return the raw return value of
  38. * the destination plugin's ::import() method. The return value from
  39. * MigrateDestinationInterface::import() is very poorly defined as "The
  40. * entity ID or an indication of success". In practice, the mapping systems
  41. * expect and all destination plugins return an array of destination
  42. * identifiers. Unfortunately these arrays are inconsistently keyed. The
  43. * core destination plugins return a numerically indexed array of
  44. * destination identifiers, but several contrib destinations return an array
  45. * of identifiers indexed by the destination keys. This method will
  46. * generally index all return arrays for consistency and to provide as much
  47. * information as possible, but this parameter is added for backwards
  48. * compatibility to allow accessing the original array.
  49. *
  50. * @return array|false
  51. * An array of destination ids for the new stub, keyed by destination id
  52. * key, or false if the stub failed.
  53. *
  54. * @throws \Drupal\Component\Plugin\Exception\PluginException
  55. * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
  56. * @throws \Drupal\migrate\MigrateException
  57. */
  58. public function createStub($migration_id, array $source_ids, array $default_values = [], $key_by_destination_ids = NULL) {
  59. $migrations = $this->migrationPluginManager->createInstances([$migration_id]);
  60. if (!$migrations) {
  61. throw new PluginNotFoundException($migration_id);
  62. }
  63. if (count($migrations) !== 1) {
  64. throw new \LogicException(sprintf('Cannot stub derivable migration "%s". You must specify the id of a specific derivative to stub.', $migration_id));
  65. }
  66. $migration = reset($migrations);
  67. $source_id_keys = array_keys($migration->getSourcePlugin()->getIds());
  68. if (count($source_id_keys) !== count($source_ids)) {
  69. throw new \InvalidArgumentException('Expected and provided source id counts do not match.');
  70. }
  71. if (array_keys($source_ids) === range(0, count($source_ids) - 1)) {
  72. $source_ids = array_combine($source_id_keys, $source_ids);
  73. }
  74. $stub = $this->doCreateStub($migration, $source_ids, $default_values);
  75. // If the return from ::import is numerically indexed, and we aren't
  76. // requesting the raw return value, index it associatively using the
  77. // destination id keys.
  78. if (($key_by_destination_ids !== FALSE) && array_keys($stub) === range(0, count($stub) - 1)) {
  79. $stub = array_combine(array_keys($migration->getDestinationPlugin()->getIds()), $stub);
  80. }
  81. return $stub;
  82. }
  83. /**
  84. * Creates a stub.
  85. *
  86. * @param \Drupal\migrate\Plugin\MigrationInterface $migration
  87. * The migration to use to create the stub.
  88. * @param array $source_ids
  89. * The source ids to map to the stub.
  90. * @param array $default_values
  91. * (optional) An array of values to include in the stub.
  92. *
  93. * @return array|bool
  94. * An array of destination ids for the stub.
  95. *
  96. * @throws \Drupal\migrate\MigrateException
  97. */
  98. protected function doCreateStub(MigrationInterface $migration, array $source_ids, array $default_values = []) {
  99. $destination = $migration->getDestinationPlugin(TRUE);
  100. $process = $migration->getProcess();
  101. $id_map = $migration->getIdMap();
  102. $migrate_executable = new MigrateExecutable($migration);
  103. $row = new Row($source_ids + $migration->getSourceConfiguration(), $migration->getSourcePlugin()->getIds(), TRUE);
  104. $migrate_executable->processRow($row, $process);
  105. foreach ($default_values as $key => $value) {
  106. $row->setDestinationProperty($key, $value);
  107. }
  108. $destination_ids = [];
  109. try {
  110. $destination_ids = $destination->import($row);
  111. }
  112. catch (\Exception $e) {
  113. $id_map->saveMessage($row->getSourceIdValues(), $e->getMessage());
  114. }
  115. if ($destination_ids) {
  116. $id_map->saveIdMapping($row, $destination_ids, MigrateIdMapInterface::STATUS_NEEDS_UPDATE);
  117. return $destination_ids;
  118. }
  119. return FALSE;
  120. }
  121. }