summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorxjm2016-12-15 16:57:35 -0600
committerxjm2016-12-15 16:57:35 -0600
commitfb17ddf07aa3a9152abb9cd804d97d9111652be7 (patch)
tree6eee2c75ad44d2c196cb1e3ba9502692d2c55206
parent38959d6366434dd5c4e5a3f1bb53af3b4d1f0534 (diff)
Issue #2828542 by claudiu.cristea, pfrenssen, cebasqueira, heddn, alexpott: Properly check if a destination folder for a file exists
-rw-r--r--core/modules/migrate/src/Plugin/migrate/process/FileCopy.php21
-rw-r--r--core/modules/migrate/tests/src/Kernel/process/FileCopyTest.php29
2 files changed, 38 insertions, 12 deletions
diff --git a/core/modules/migrate/src/Plugin/migrate/process/FileCopy.php b/core/modules/migrate/src/Plugin/migrate/process/FileCopy.php
index c68fe34..9aa5900 100644
--- a/core/modules/migrate/src/Plugin/migrate/process/FileCopy.php
+++ b/core/modules/migrate/src/Plugin/migrate/process/FileCopy.php
@@ -112,20 +112,17 @@ class FileCopy extends ProcessPluginBase implements ContainerFactoryPluginInterf
return $destination;
}
- $replace = $this->getOverwriteMode();
- // We attempt the copy/move first to avoid calling file_prepare_directory()
- // any more than absolutely necessary.
- $final_destination = $this->writeFile($source, $destination, $replace);
- if ($final_destination) {
- return $final_destination;
- }
- // If writeFile didn't work, make sure there's a writable directory in
- // place.
+ // Check if a writable directory exists, and if not try to create it.
$dir = $this->getDirectory($destination);
- if (!file_prepare_directory($dir, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) {
- throw new MigrateException("Could not create or write to directory '$dir'");
+ // If the directory exists and is writable, avoid file_prepare_directory()
+ // call and write the file to destination.
+ if (!is_dir($dir) || !is_writable($dir)) {
+ if (!file_prepare_directory($dir, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) {
+ throw new MigrateException("Could not create or write to directory '$dir'");
+ }
}
- $final_destination = $this->writeFile($source, $destination, $replace);
+
+ $final_destination = $this->writeFile($source, $destination, $this->getOverwriteMode());
if ($final_destination) {
return $final_destination;
}
diff --git a/core/modules/migrate/tests/src/Kernel/process/FileCopyTest.php b/core/modules/migrate/tests/src/Kernel/process/FileCopyTest.php
index ee75e45..451d832 100644
--- a/core/modules/migrate/tests/src/Kernel/process/FileCopyTest.php
+++ b/core/modules/migrate/tests/src/Kernel/process/FileCopyTest.php
@@ -4,6 +4,7 @@ namespace Drupal\Tests\migrate\Kernel\process;
use Drupal\Core\StreamWrapper\StreamWrapperInterface;
use Drupal\KernelTests\Core\File\FileTestBase;
+use Drupal\migrate\MigrateException;
use Drupal\migrate\Plugin\migrate\process\FileCopy;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\Plugin\MigrateProcessInterface;
@@ -12,6 +13,8 @@ use Drupal\migrate\Row;
/**
* Tests the file_copy process plugin.
*
+ * @coversDefaultClass \Drupal\migrate\Plugin\migrate\process\FileCopy
+ *
* @group migrate
*/
class FileCopyTest extends FileTestBase {
@@ -121,6 +124,32 @@ class FileCopyTest extends FileTestBase {
}
/**
+ * Tests that non-writable destination throw an exception.
+ *
+ * @covers ::transform
+ */
+ public function testNonWritableDestination() {
+ $source = $this->createUri('file.txt', NULL, 'temporary');
+
+ // Create the parent location.
+ $this->createDirectory('public://dir');
+
+ // Copy the file under public://dir/subdir1/.
+ $this->doTransform($source, 'public://dir/subdir1/file.txt');
+
+ // Check that 'subdir1' was created and the file was successfully migrated.
+ $this->assertFileExists('public://dir/subdir1/file.txt');
+
+ // Remove all permissions from public://dir to trigger a failure when
+ // trying to create a subdirectory 'subdir2' inside public://dir.
+ $this->fileSystem->chmod('public://dir', 0);
+
+ // Check that the proper exception is raised.
+ $this->setExpectedException(MigrateException::class, "Could not create or write to directory 'public://dir/subdir2'");
+ $this->doTransform($source, 'public://dir/subdir2/file.txt');
+ }
+
+ /**
* Test the 'rename' overwrite mode.
*/
public function testRenameFile() {