Skip to content

Commit f39483c

Browse files
authored
Merge pull request #202 from eri-trabiccolo/issue/146
Added feature to import media into a specific directory
2 parents 2db6ddc + e2c0567 commit f39483c

2 files changed

Lines changed: 89 additions & 7 deletions

File tree

features/media-import.feature

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,3 +286,35 @@ Feature: Manage WordPress attachments
286286
"""
287287
Error: Invalid value for <porcelain>: invalid. Expected flag or 'url'.
288288
"""
289+
290+
Scenario: Upload files into a custom directory, relative to ABSPATH, when --destination-dir flag is applied.
291+
Given download:
292+
| path | url |
293+
| {CACHE_DIR}/large-image.jpg | http://wp-cli.org/behat-data/large-image.jpg |
294+
When I run `wp media import --destination-dir="foo" {CACHE_DIR}/large-image.jpg --porcelain=url`
295+
296+
Then STDOUT should not contain:
297+
"""
298+
https://example.com/wp-content/uploads/
299+
"""
300+
301+
And STDOUT should contain:
302+
"""
303+
https://example.com/foo/large-image.jpg
304+
"""
305+
306+
Scenario: Upload files into a custom directory, not relative to ABSPATH, when --destination-dir flag is applied.
307+
Given download:
308+
| path | url |
309+
| {CACHE_DIR}/large-image.jpg | http://wp-cli.org/behat-data/large-image.jpg |
310+
When I run `wp media import --destination-dir="{RUN_DIR}/foo" {CACHE_DIR}/large-image.jpg --porcelain=url`
311+
312+
Then STDOUT should not contain:
313+
"""
314+
https://example.com/wp-content/uploads/
315+
"""
316+
317+
And STDOUT should contain:
318+
"""
319+
/foo/large-image.jpg
320+
"""

src/Media_Command.php

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ class Media_Command extends WP_CLI_Command {
4949
*/
5050
const WP_CLEAR_OBJECT_CACHE_INTERVAL = 500;
5151

52+
/**
53+
* @var string|null
54+
*/
55+
private $destination_dir;
56+
5257
/**
5358
* Regenerates thumbnails for one or more attachments.
5459
*
@@ -216,7 +221,13 @@ public function regenerate( $args, $assoc_args = array() ) {
216221
*
217222
* [--skip-copy]
218223
* : If set, media files (local only) are imported to the library but not moved on disk.
219-
* File names will not be run through wp_unique_filename() with this set.
224+
* File names will not be run through wp_unique_filename() with this set. When used, files
225+
* will remain at their current location and will not be copied into any destination directory.
226+
*
227+
* [--destination-dir=<destination-dir>]
228+
* : Path to the destination directory for uploaded imported files.
229+
* Can be absolute or relative to ABSPATH. Ignored when used together with --skip-copy, as
230+
* files are not moved on disk in that case.
220231
*
221232
* [--preserve-filetime]
222233
* : Use the file modified time as the post published & modified dates.
@@ -266,12 +277,13 @@ public function import( $args, $assoc_args = array() ) {
266277
$assoc_args = wp_parse_args(
267278
$assoc_args,
268279
array(
269-
'file_name' => '',
270-
'title' => '',
271-
'caption' => '',
272-
'alt' => '',
273-
'desc' => '',
274-
'post_name' => '',
280+
'file_name' => '',
281+
'title' => '',
282+
'caption' => '',
283+
'alt' => '',
284+
'desc' => '',
285+
'post_name' => '',
286+
'destination-dir' => '',
275287
)
276288
);
277289

@@ -411,6 +423,13 @@ public function import( $args, $assoc_args = array() ) {
411423
}
412424
wp_update_attachment_metadata( $success, wp_generate_attachment_metadata( $success, $file ) );
413425
} else {
426+
427+
$destdir = Utils\get_flag_value( $assoc_args, 'destination-dir' );
428+
if ( ! empty( $destdir ) ) {
429+
$this->destination_dir = $destdir;
430+
add_filter( 'upload_dir', [ $this, 'filter_upload_dir' ], PHP_INT_MAX );
431+
}
432+
414433
// Deletes the temporary file.
415434
$success = media_handle_sideload( $file_array, $assoc_args['post_id'], $assoc_args['title'], $post_array );
416435
if ( is_wp_error( $success ) ) {
@@ -468,6 +487,8 @@ public function import( $args, $assoc_args = array() ) {
468487
++$successes;
469488
}
470489

490+
remove_filter( 'upload_dir', [ $this, 'filter_upload_dir' ], PHP_INT_MAX );
491+
471492
// Report the result of the operation
472493
if ( ! Utils\get_flag_value( $assoc_args, 'porcelain' ) ) {
473494
Utils\report_batch_operation_results( $noun, 'import', count( $args ), $successes, $errors );
@@ -939,6 +960,35 @@ private function remove_image_size_filters( $image_size_filters ) {
939960
}
940961
}
941962

963+
public function filter_upload_dir( $uploads ) {
964+
if ( ! $this->destination_dir ) {
965+
return $uploads;
966+
}
967+
968+
$upload_dir = $this->destination_dir;
969+
970+
if ( 0 !== strpos( $this->destination_dir, ABSPATH ) ) {
971+
// $dir is absolute, $upload_dir is (maybe) relative to ABSPATH.
972+
$dir = path_join( ABSPATH, $this->destination_dir );
973+
} else {
974+
$dir = $this->destination_dir;
975+
// normalize $upload_dir.
976+
$upload_dir = substr( $this->destination_dir, strlen( ABSPATH ) );
977+
}
978+
979+
$siteurl = get_option( 'siteurl' );
980+
$url = trailingslashit( $siteurl ) . $upload_dir;
981+
982+
return [
983+
'path' => $this->destination_dir,
984+
'url' => $url,
985+
'subdir' => '',
986+
'basedir' => $this->destination_dir,
987+
'baseurl' => $url,
988+
'error' => false,
989+
];
990+
}
991+
942992
// Update attachment sizes metadata just for a particular intermediate image size.
943993
private function update_attachment_metadata_for_image_size( $id, $new_metadata, $image_size, $metadata ) {
944994

0 commit comments

Comments
 (0)