diff --git a/features/media-import.feature b/features/media-import.feature index aa8562fc..9ef2032f 100644 --- a/features/media-import.feature +++ b/features/media-import.feature @@ -286,3 +286,40 @@ Feature: Manage WordPress attachments """ Error: Invalid value for : 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 - ] * : ID of the post to attach the imported files to. @@ -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( @@ -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'] ) ) {