2c2 < index a4693cf..d1c9ea0 100644 --- > index a4693cf..7abb59c 100644 5c5 < @@ -1,21 +1,40 @@ --- > @@ -1,21 +1,41 @@ 8,9c8,9 < +# Every migration that references a file by fid should specify this migration < +# as an optional dependency. --- > +# Every migration that references a file by Drupal 6 fid should specify this > +# migration as an optional dependency. 18,19c18,20 < + # represents the fully qualified path relative to which uris in the files < + # table are specified, and must end with a /. --- > + # represents the fully qualified path relative to which URIs in the files > + # table are specified, and must end with a /. See source_full_path > + # configuration in this migration's process pipeline as an example. 50c51 < index b10cca6..abda991 100644 --- > index b10cca6..ffd85ab 100644 53c54,61 < @@ -6,10 +6,28 @@ migration_tags: --- > @@ -1,15 +1,34 @@ > -# Every migration that references a file by fid should specify this migration > -# as an optional dependency. > +# Every migration that references a file by Drupal 7 fid should specify this > +# migration as an optional dependency. > id: d7_file > label: Files > migration_tags: 60c68,69 < + # table are specified, and must end with a /. --- > + # table are specified, and must end with a /. See source_full_path > + # configuration in this migration's process pipeline as an example. 83c92 < @@ -22,5 +40,3 @@ process: --- > @@ -22,5 +41,3 @@ process: 90c99 < index 900db6a..d234be2 100644 --- > index 900db6a..6374251 100644 177c186 < + // we're loading the matching uri. --- > + // we're loading the matching URI. 687c696 < index ef713c8..23bacf7 100644 --- > index ef713c8..8a0dc89 100644 716c725 < + $source['constants']['source_base_path'] = DRUPAL_ROOT . '/'; --- > + $source['constants']['source_base_path'] = \Drupal::root() . '/'; 783c792 < index 0000000..eafa2f4 --- > index 0000000..c0d5109 786c795 < @@ -0,0 +1,59 @@ --- > @@ -0,0 +1,65 @@ 802a812,814 > + /** > + * @inheritdoc > + */ 808c820,823 < + * Cover various encoding scenarios. --- > + * The data provider for testing URL encoding scenarios. > + * > + * @return array > + * An array of URLs to test. 810,821c825,833 < + public function testUrls() { < + $values = [ < + // A URL with no characters requiring encoding. < + 'http://example.com/normal_url.html' => 'http://example.com/normal_url.html', < + // The definitive use case - encoding spaces in URLs. < + 'http://example.com/url with spaces.html' => 'http://example.com/url%20with%20spaces.html', < + // Local filespecs should not be transformed, with or without spaces. < + '/tmp/normal.txt' => '/tmp/normal.txt', < + '/tmp/with spaces.txt' => '/tmp/with spaces.txt', < + // Make sure URL characters (:, ?, &) are not encoded but others are. < + 'https://example.com/?a=b@c&d=e+f%' => 'https://example.com/?a%3Db%40c&d%3De%2Bf%25', < + ]; --- > + public function urlDataProvider() { > + return array( > + 'A URL with no characters requiring encoding' => array('http://example.com/normal_url.html', 'http://example.com/normal_url.html'), > + 'The definitive use case - encoding spaces in URLs' => array('http://example.com/url with spaces.html', 'http://example.com/url%20with%20spaces.html'), > + 'Local filespecs without spaces should not be transformed' => array('/tmp/normal.txt', '/tmp/normal.txt'), > + 'Local filespecs with spaces should not be transformed' => array('/tmp/with spaces.txt', '/tmp/with spaces.txt'), > + 'Make sure URL characters (:, ?, &) are not encoded but others are.' => array('https://example.com/?a=b@c&d=e+f%', 'https://example.com/?a%3Db%40c&d%3De%2Bf%25'), > + ); > + } 823,825c835,840 < + foreach ($values as $input => $output) { < + $this->assertEquals($output, $this->doTransform($input)); < + } --- > + /** > + * Cover various encoding scenarios. > + * @dataProvider urlDataProvider > + */ > + public function testUrls($input, $output) { > + $this->assertEquals($output, $this->doTransform($input)); 870c885 < index 0000000..4644e37 --- > index 0000000..9eb7804 961c976 < + throw new MigrateException("File '$source' does not exist."); --- > + throw new MigrateException("File '$source' does not exist"); 976,977c991,992 < + if (!file_prepare_directory($dir, FILE_CREATE_DIRECTORY)) { < + throw new MigrateException("Could not create directory '$dir'"); --- > + if (!file_prepare_directory($dir, FILE_CREATE_DIRECTORY + FILE_MODIFY_PERMISSIONS)) { > + throw new MigrateException("Could not create, or could not write to directory '$dir'"); 982c997 < + throw new MigrateException("File $source could not be copied to $destination."); --- > + throw new MigrateException("File $source could not be copied to $destination"); 1083c1098 < index 0000000..4d966a6 --- > index 0000000..2d9c4de 1086c1101 < @@ -0,0 +1,39 @@ --- > @@ -0,0 +1,51 @@ 1091a1107 > +use Drupal\migrate\MigrateException; 1112,1116c1128,1145 < + if (strpos($value, '://') > 0) { < + $components = explode('/', $value); < + foreach ($components as $key => $component) { < + // urlencode() would convert spaces to + signs. < + $components[$key] = rawurlencode($component); --- > + if (is_string($value) && strpos($value, '://') > 0) { > + // URL encode everything after the hostname. > + $parsed_url = parse_url($value); > + // Fail on seriously malformed URLs. > + if ($parsed_url === FALSE) { > + throw new MigrateException("Value '$value' is not a valid URL"); > + } > + // Iterate over specific pieces of the URL rawurlencoding each one. > + $url_parts_to_encode = array('path', 'query', 'fragment'); > + foreach ($parsed_url as $parsed_url_key => $parsed_url_value) { > + if (in_array($parsed_url_key, $url_parts_to_encode)) { > + $components = explode('/', $parsed_url_value); > + // urlencode() would convert spaces to + signs. > + foreach ($components as $key => $component) { > + $components[$key] = rawurlencode($component); > + } > + $parsed_url[$parsed_url_key] = implode('/', $components); > + } 1118,1120c1147 < + $value = implode('/', $components); < + // Do not encode URL syntax characters. < + $value = str_replace(['%3A', '%3F', '%26'], [':', '?', '&'], $value); --- > + $value = http_build_url($parsed_url); 1127c1154 < index 4ba4d2b..d18d6e1 100644 --- > index 4ba4d2b..404ca50 100644 1130c1157,1166 < @@ -137,6 +137,16 @@ protected function prepareMigrations(array $id_mappings) { --- > @@ -7,6 +7,8 @@ > use Drupal\migrate\MigrateExecutable; > use Drupal\migrate\MigrateMessageInterface; > use Drupal\migrate\Plugin\MigrateIdMapInterface; > +use Drupal\migrate\Plugin\Migration; > +use Drupal\migrate\Plugin\MigrationInterface; > use Drupal\migrate\Row; > > /** > @@ -137,6 +139,16 @@ protected function prepareMigrations(array $id_mappings) { 1139c1175 < + protected function processMigration($migration) { --- > + protected function processMigration(MigrationInterface $migration) { 1147c1183 < @@ -152,6 +162,8 @@ protected function executeMigration($migration) { --- > @@ -152,6 +164,8 @@ protected function executeMigration($migration) { 1158c1194 < index 0000000..81f2b85 --- > index 0000000..3265b86 1161c1197 < @@ -0,0 +1,148 @@ --- > @@ -0,0 +1,139 @@ 1193a1230 > + * @dataProvider localFileDataCopyProvider 1195,1197c1232,1233 < + public function testSuccessfulCopies() { < + foreach ($this->localFileDataCopyProvider() as $data) { < + list($source_path, $destination_path, $expected) = $data; --- > + public function testSuccessfulCopies($data) { > + list($source_path, $destination_path) = $data; 1199,1200c1235,1236 < + $message = $expected ? sprintf('File %s exists', $destination_path) : sprintf('File %s does not exist', $destination_path); < + $this->assertSame($expected, is_file($destination_path), $message); --- > + $message = sprintf('File %s exists', $destination_path); > + $this->assertTrue(is_file($destination_path), $message); 1202,1204c1238 < + $message = $expected ? sprintf('File %s exists', $source_path) : sprintf('File %s does not exist', $source_path); < + $this->assertSame($expected, is_file($source_path), $message); < + } --- > + $this->assertTrue(is_file($source_path), $message); 1215,1222c1249,1253 < + return [ < + // Test a local to local copy. < + [$this->root . '/core/modules/simpletest/files/image-test.jpg', 'public://file1.jpg', TRUE], < + // Test a temporary file using an absolute path. < + ['/tmp/test-file.jpg', 'temporary://test.jpg', TRUE], < + // Test a temporary file using a relative path. < + ['/tmp/test-file.jpg', 'temporary://core/modules/simpletest/files/test.jpg', TRUE], < + ]; --- > + return array( > + 'local to local copy' => array($this->root . '/core/modules/simpletest/files/image-test.jpg', 'public://file1.jpg'), > + 'Temporary file using an absolute path' => array('/tmp/test-file.jpg', 'temporary://test.jpg'), > + 'Temporary file using a relative path' => array('/tmp/test-file.jpg', 'temporary://core/modules/simpletest/files/test.jpg'), > + ); 1226a1258 > + * @dataProvider localFileDataMoveProvider 1229,1236c1261,1266 < + foreach ($this->localFileDataMoveProvider() as $data) { < + list($source_path, $destination_path, $expected) = $data; < + $this->doImport($source_path, $destination_path, ['move' => TRUE]); < + $message = $expected ? sprintf('File %s exists', $destination_path) : sprintf('File %s does not exist', $destination_path); < + $this->assertSame($expected, is_file($destination_path), $message); < + $message = $expected ? sprintf('File %s does not exist', $source_path) : sprintf('File %s exists', $source_path); < + $this->assertSame($expected, !is_file($source_path), $message); < + } --- > + list($source_path, $destination_path) = $data; > + $this->doImport($source_path, $destination_path, ['move' => TRUE]); > + $message = sprintf('File %s exists', $destination_path); > + $this->assertTrue(is_file($destination_path), $message); > + $message = sprintf('File %s does not exist', $source_path); > + $this->assertTrue(!is_file($source_path), $message); 1250,1257c1280,1284 < + return [ < + // Test a local to local copy. < + [$local_file, 'public://file1.jpg', TRUE], < + // Test a temporary file using an absolute path. < + ['/tmp/test-file.jpg', 'temporary://test.jpg', TRUE], < + // Test a temporary file using a relative path. < + ['/tmp/test-file2.jpg', 'temporary://core/modules/simpletest/files/test.jpg', TRUE], < + ]; --- > + return array( > + 'Local to local copy' => array($local_file, 'public://file1.jpg'), > + 'Temporary file using an absolute path.' => array('/tmp/test-file.jpg', 'temporary://test.jpg'), > + 'Temporary file using a relative path' => array('/tmp/test-file2.jpg', 'temporary://core/modules/simpletest/files/test.jpg'), > + ); 1312c1339 < index 0000000..cdbe073 --- > index 0000000..a0dcdfc 1315c1342 < @@ -0,0 +1,59 @@ --- > @@ -0,0 +1,65 @@ 1331a1359,1361 > + /** > + * @inheritdoc > + */ 1337c1367,1370 < + * Cover various encoding scenarios. --- > + * The data provider for testing URL encoding scenarios. > + * > + * @return array > + * An array of URLs to test. 1339,1350c1372,1380 < + public function testUrls() { < + $values = [ < + // A URL with no characters requiring encoding. < + 'http://example.com/normal_url.html' => 'http://example.com/normal_url.html', < + // The definitive use case - encoding spaces in URLs. < + 'http://example.com/url with spaces.html' => 'http://example.com/url%20with%20spaces.html', < + // Local filespecs should not be transformed, with or without spaces. < + '/tmp/normal.txt' => '/tmp/normal.txt', < + '/tmp/with spaces.txt' => '/tmp/with spaces.txt', < + // Make sure URL characters (:, ?, &) are not encoded but others are. < + 'https://example.com/?a=b@c&d=e+f%' => 'https://example.com/?a%3Db%40c&d%3De%2Bf%25', < + ]; --- > + public function urlDataProvider() { > + return array( > + 'A URL with no characters requiring encoding' => array('http://example.com/normal_url.html', 'http://example.com/normal_url.html'), > + 'The definitive use case - encoding spaces in URLs' => array('http://example.com/url with spaces.html', 'http://example.com/url%20with%20spaces.html'), > + 'Local filespecs without spaces should not be transformed' => array('/tmp/normal.txt', '/tmp/normal.txt'), > + 'Local filespecs with spaces should not be transformed' => array('/tmp/with spaces.txt', '/tmp/with spaces.txt'), > + 'Make sure URL characters (:, ?, &) are not encoded but others are.' => array('https://example.com/?a=b@c&d=e+f%', 'https://example.com/?a%3Db%40c&d%3De%2Bf%25'), > + ); > + } 1352,1354c1382,1387 < + foreach ($values as $input => $output) { < + $this->assertEquals($output, $this->doTransform($input)); < + } --- > + /** > + * Cover various encoding scenarios. > + * @dataProvider urlDataProvider > + */ > + public function testUrls($input, $output) { > + $this->assertEquals($output, $this->doTransform($input)); 1361c1394 < + * Url to be encoded. --- > + * URL to be encoded. 1364c1397 < + * Encoded url. --- > + * Encoded URL. 1392c1425 < index e4d572a..3677373 100644 --- > index e4d572a..50017cb 100644 1400c1433 < + # represents the fully qualified path relative to which uris in the files --- > + # represents the fully qualified path relative to which URIs in the files 1434c1467 < + # Every migration that references a file by fid should specify d6_file as an --- > + # Every migration that references a file by Drupal 6 fid should specify d6_file as an