Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions features/media-import.feature
Original file line number Diff line number Diff line change
Expand Up @@ -286,3 +286,40 @@ Feature: Manage WordPress attachments
"""
Error: Invalid value for <porcelain>: invalid. Expected flag or 'url'.
"""

Scenario: Import media from STDIN
Given download:
| path | url |
| {CACHE_DIR}/codeispoetry.png | http://wp-cli.org/behat-data/codeispoetry.png |

When I run `cat {CACHE_DIR}/codeispoetry.png | wp media import - --title="From STDIN" --porcelain`
Then save STDOUT as {ATTACHMENT_ID}

When I run `wp post get {ATTACHMENT_ID} --field=title`
Then STDOUT should be:
"""
From STDIN
"""

Scenario: Import media from STDIN with file_name
Given download:
| path | url |
| {CACHE_DIR}/codeispoetry.png | http://wp-cli.org/behat-data/codeispoetry.png |

When I run `cat {CACHE_DIR}/codeispoetry.png | wp media import - --file_name=my-image.png --porcelain`
Then save STDOUT as {ATTACHMENT_ID}

When I run `wp post get {ATTACHMENT_ID} --field=name`
Then STDOUT should be:
"""
my-image-png
"""
# Note: WordPress sanitizes the post_name (slug) by converting dots to hyphens

Scenario: Fail to import from STDIN when no input provided
When I try `wp media import - </dev/null`
Then STDERR should contain:
"""
Warning: Unable to import file from STDIN. Reason: No input provided.
"""
And the return code should be 1
110 changes: 84 additions & 26 deletions src/Media_Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@
* Imported file '/home/person/Downloads/image.png' as attachment ID 1753 and attached to post 123 as featured image.
* Success: Imported 1 of 1 images.
*
* # Import an image from STDIN.
* $ curl http://example.com/image.jpg | wp media import -
* Imported file 'STDIN' as attachment ID 1754.
* Success: Imported 1 of 1 items.
*
* # List all registered image sizes
* $ wp media image-size
* +---------------------------+-------+--------+-------+
Expand Down Expand Up @@ -192,6 +197,7 @@ public function regenerate( $args, $assoc_args = array() ) {
* : Path to file or files to be imported. Supports the glob(3) capabilities of the current shell.
* If file is recognized as a URL (for example, with a scheme of http or ftp), the file will be
* downloaded to a temp file before being sideloaded.
* Use '-' to read file data from STDIN.
*
* [--post_id=<post_id>]
* : ID of the post to attach the imported files to.
Expand Down Expand Up @@ -261,6 +267,11 @@ public function regenerate( $args, $assoc_args = array() ) {
* # Get the URL for an attachment after import.
* $ wp media import http://s.wordpress.org/style/images/wp-header-logo.png --porcelain | xargs -I {} wp post list --post__in={} --field=url --post_type=attachment
* http://wordpress-develop.dev/wp-header-logo/
*
* # Import an image from STDIN.
* $ curl http://example.com/image.jpg | wp media import - --title="From STDIN"
* Imported file from STDIN as attachment ID 1756.
* Success: Imported 1 of 1 items.
*/
public function import( $args, $assoc_args = array() ) {
$assoc_args = wp_parse_args(
Expand Down Expand Up @@ -309,41 +320,88 @@ public function import( $args, $assoc_args = array() ) {
Utils\wp_clear_object_cache();
}

// phpcs:ignore WordPress.WP.AlternativeFunctions.parse_url_parse_url -- parse_url will only be used in absence of wp_parse_url.
$is_file_remote = function_exists( 'wp_parse_url' ) ? wp_parse_url( $file, PHP_URL_HOST ) : parse_url( $file, PHP_URL_HOST );
$orig_filename = $file;
$file_time = '';
// Handle STDIN input
if ( '-' === $file ) {
if ( ! Utils\has_stdin() ) {
WP_CLI::warning( 'Unable to import file from STDIN. Reason: No input provided.' );
++$errors;
continue;
}

if ( empty( $is_file_remote ) ) {
if ( ! file_exists( $file ) ) {
WP_CLI::warning( "Unable to import file '$file'. Reason: File doesn't exist." );
// Read from STDIN and save to a temporary file
$stdin_content = file_get_contents( 'php://stdin' );
if ( false === $stdin_content || empty( $stdin_content ) ) {
WP_CLI::warning( 'Unable to import file from STDIN. Reason: No input provided.' );
++$errors;
continue;
}
if ( Utils\get_flag_value( $assoc_args, 'skip-copy' ) ) {
$tempfile = $file;
} else {
$tempfile = $this->make_copy( $file );

// Create a temporary file to store STDIN content
$tempfile = wp_tempnam( 'wp-media-import-' );
if ( false === file_put_contents( $tempfile, $stdin_content ) ) {
WP_CLI::warning( 'Unable to import file from STDIN. Reason: Could not write to temporary file.' );
++$errors;
continue;
}
$name = Utils\basename( $file );

if ( Utils\get_flag_value( $assoc_args, 'preserve-filetime' ) ) {
$file_time = @filemtime( $file );
// Determine file extension from content
$mimetype = mime_content_type( $tempfile );

// Map MIME type to extension
$ext = '';
if ( $mimetype && function_exists( 'wp_get_mime_types' ) ) {
$mime_types = wp_get_mime_types();
foreach ( $mime_types as $exts => $mime ) {
if ( $mime === $mimetype ) {
$ext_array = explode( '|', $exts );
$ext = '.' . $ext_array[0];
break;
}
}
}

// Generate filename with proper extension
$name = 'stdin-' . time() . $ext;

$orig_filename = 'STDIN';
$file_time = '';
} else {
$tempfile = download_url( $file );
if ( is_wp_error( $tempfile ) ) {
WP_CLI::warning(
sprintf(
"Unable to import file '%s'. Reason: %s",
$file,
implode( ', ', $tempfile->get_error_messages() )
)
);
++$errors;
continue;
// phpcs:ignore WordPress.WP.AlternativeFunctions.parse_url_parse_url -- parse_url will only be used in absence of wp_parse_url.
$is_file_remote = function_exists( 'wp_parse_url' ) ? wp_parse_url( $file, PHP_URL_HOST ) : parse_url( $file, PHP_URL_HOST );
$orig_filename = $file;
$file_time = '';

if ( empty( $is_file_remote ) ) {
if ( ! file_exists( $file ) ) {
WP_CLI::warning( "Unable to import file '$file'. Reason: File doesn't exist." );
++$errors;
continue;
}
if ( Utils\get_flag_value( $assoc_args, 'skip-copy' ) ) {
$tempfile = $file;
} else {
$tempfile = $this->make_copy( $file );
}
$name = Utils\basename( $file );

if ( Utils\get_flag_value( $assoc_args, 'preserve-filetime' ) ) {
$file_time = @filemtime( $file );
}
} else {
$tempfile = download_url( $file );
if ( is_wp_error( $tempfile ) ) {
WP_CLI::warning(
sprintf(
"Unable to import file '%s'. Reason: %s",
$file,
implode( ', ', $tempfile->get_error_messages() )
)
);
++$errors;
continue;
}
$name = strtok( Utils\basename( $file ), '?' );
}
$name = strtok( Utils\basename( $file ), '?' );
}

if ( ! empty( $assoc_args['file_name'] ) ) {
Expand Down
Loading