diff -u b/core/modules/migrate/src/Plugin/migrate/destination/EntityFile.php b/core/modules/migrate/src/Plugin/migrate/destination/EntityFile.php --- b/core/modules/migrate/src/Plugin/migrate/destination/EntityFile.php +++ b/core/modules/migrate/src/Plugin/migrate/destination/EntityFile.php @@ -10,6 +10,8 @@ use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\File\FileSystemInterface; +use Drupal\Core\StreamWrapper\LocalStream; +use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface; use Drupal\migrate\Entity\MigrationInterface; use Drupal\migrate\Row; use Drupal\migrate\MigrateException; @@ -26,6 +28,11 @@ class EntityFile extends EntityContentBase { /** + * @var \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface + */ + protected $streamWrappers; + + /** * @var \Drupal\Core\File\FileSystemInterface */ protected $fileSystem; @@ -33,7 +40,7 @@ /** * {@inheritdoc} */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, EntityManagerInterface $entity_manager, FileSystemInterface $file_system) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, EntityManagerInterface $entity_manager, StreamWrapperManagerInterface $stream_wrappers, FileSystemInterface $file_system) { $configuration += array( 'source_base_path' => '', 'source_path_property' => 'filepath', @@ -43,6 +50,7 @@ ); parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles, $entity_manager); + $this->streamWrappers = $stream_wrappers; $this->fileSystem = $file_system; } @@ -59,6 +67,7 @@ $container->get('entity.manager')->getStorage($entity_type), array_keys($container->get('entity.manager')->getBundleInfo($entity_type)), $container->get('entity.manager'), + $container->get('stream_wrapper_manager'), $container->get('file_system') ); } @@ -86,7 +95,7 @@ } // If the start and end file is exactly the same, there is nothing to do. - if ($this->fileSystem->realpath($source) === $this->fileSystem->realpath($destination)) { + if ($this->isLocationUnchanged($source, $destination)) { return parent::import($row, $old_destination_id_values); } @@ -120,6 +129,42 @@ } /** + * Returns if the source and destination URIs represent identical paths. + * If either URI is a remote stream, will return FALSE. + * + * @param string $source + * The source URI. + * @param string $destination + * The destination URI. + * + * @return boolean + */ + protected function isLocationUnchanged($source, $destination) { + if ($this->isLocalTransfer($source, $destination)) { + return $this->fileSystem->realpath($source) === $this->fileSystem->realpath($destination); + } + else { + return FALSE; + } + } + + /** + * Returns if both the source and destination URIs are local streams. + * + * @param string $source + * The source URI. + * @param string $destination + * The destination URI. + * + * @return boolean + */ + protected function isLocalTransfer($source, $destination) { + return + $this->streamWrappers->getViaUri($source) instanceof LocalStream + && $this->streamWrappers->getViaUri($destination) instanceof LocalStream; + } + + /** * Urlencode all the components of a remote filename. * * @param string $filename diff -u b/core/modules/migrate/tests/src/Unit/destination/EntityFileTest.php b/core/modules/migrate/tests/src/Unit/destination/EntityFileTest.php --- b/core/modules/migrate/tests/src/Unit/destination/EntityFileTest.php +++ b/core/modules/migrate/tests/src/Unit/destination/EntityFileTest.php @@ -39,6 +39,7 @@ public function setUp() { parent::setUp(); $this->destination = new TestEntityFile([]); + $this->destination->streamWrappers = \Drupal::getContainer()->get('stream_wrapper_manager'); $this->destination->fileSystem = \Drupal::getContainer()->get('file_system'); $this->installConfig(['system']); @@ -84,12 +85,16 @@ * Test that non-existent files throw an exception. */ public function testNonExistentSourceFile() { + $destination = '/non/existent/file'; try { - $this->doImport(['filepath' => '/none/existent/file'], 'public://wontmatter.jpg'); + // If this test passes, doImport() will raise a MigrateException and + // we'll never reach fail(). + $this->doImport(['filepath' => $destination], 'public://wontmatter.jpg'); + $this->fail('Expected Drupal\migrate\MigrateException when importing ' . $destination); + } + catch (MigrateException $e) { + $this->assertIdentical($e->getMessage(), 'File ' . $destination . ' could not be copied to public://wontmatter.jpg.'); } - catch (MigrateException $e) {} - $destination = '/none/existent/file'; - $this->assertIdentical($e->getMessage(), 'File ' . $destination . ' could not be copied to public://wontmatter.jpg.'); } /** @@ -135,6 +140,11 @@ public $configuration; /** + * @var \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface + */ + public $streamWrappers; + + /** * @var \Drupal\Core\File\FileSystemInterface */ public $fileSystem;