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 @@ -72,6 +72,15 @@ $source = $this->configuration['source_base_path'] . $file; $dirname = $this->fileSystem->dirname($destination); + // It's pretty safe to assume that $source exists. $destination, on the + // other hand, might not. So we need to do a little dancing to prepare + // the destination path. The issue is that, for URIs like public://foo.txt, + // FileSystemInterface::dirname() will return public:// -- which will + // be roundly rejected by file_prepare_directory(). So if dirname() returned + // such a URI, translate it to a path for file_prepare_directory(). + if (preg_match('#://#', $dirname)) { + $dirname = $this->fileSystem->realpath($dirname); + } if (!file_prepare_directory($dirname, FILE_CREATE_DIRECTORY)) { throw new MigrateException(t('Could not create directory %dirname', array('%dirname' => $dirname))); } 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->fileSystem = \Drupal::getContainer()->get('file_system'); $this->installConfig(['system']); file_put_contents('/tmp/test-file.jpg', ''); @@ -70,7 +71,7 @@ [['filepath' => 'core/modules/simpletest/files/image-test.jpg'], 'public://file1.jpg', TRUE, DRUPAL_ROOT . '/'], // Test a temporary file using an absolute path. [['filepath' => '/tmp/test-file.jpg'], 'temporary://test.jpg', TRUE, ''], - // Test a temporary file using an relative path. + // Test a temporary file using a relative path. [['filepath' => 'test-file.jpg'], 'temporary://core/modules/simpletest/files/test.jpg', TRUE, '/tmp/'], // Test a remote path to local. [['filepath' => 'core/modules/simpletest/files/image-test.jpg'], 'public://remote-file.jpg', TRUE, $base_url . '/'], @@ -79,7 +80,6 @@ ]; } - /** * Test that non-existent files throw an exception. */ @@ -134,6 +134,11 @@ */ public $configuration; + /** + * @var \Drupal\Core\File\FileSystemInterface + */ + public $fileSystem; + public function __construct($configuration) { $configuration += array( 'source_base_path' => '',