diff --git a/plugins/woocommerce/changelog/allow-inline-downloads b/plugins/woocommerce/changelog/allow-inline-downloads new file mode 100644 index 00000000000..fe0821efd90 --- /dev/null +++ b/plugins/woocommerce/changelog/allow-inline-downloads @@ -0,0 +1,4 @@ +Significance: minor +Type: enhancement + +Add option to serve downloadable files inline. diff --git a/plugins/woocommerce/includes/admin/settings/class-wc-settings-products.php b/plugins/woocommerce/includes/admin/settings/class-wc-settings-products.php index fdd8072a2ae..0f9751e31c9 100644 --- a/plugins/woocommerce/includes/admin/settings/class-wc-settings-products.php +++ b/plugins/woocommerce/includes/admin/settings/class-wc-settings-products.php @@ -421,6 +421,16 @@ class WC_Settings_Products extends WC_Settings_Page { 'autoload' => false, ), + array( + 'title' => __( 'Open in browser', 'woocommerce' ), + 'desc' => __( 'Open downloadable files in the browser, instead of saving them to the device.', 'woocommerce' ), + 'id' => 'woocommerce_downloads_deliver_inline', + 'type' => 'checkbox', + 'default' => false, + 'desc_tip' => __( 'Customers can still save the file to their device, but by default file will be opened instead of being downloaded (does not work with redirects).', 'woocommerce' ), + 'autoload' => false, + ), + array( 'title' => __( 'Filename', 'woocommerce' ), 'desc' => __( 'Append a unique string to filename for security', 'woocommerce' ), diff --git a/plugins/woocommerce/includes/class-wc-download-handler.php b/plugins/woocommerce/includes/class-wc-download-handler.php index 29d7261f76b..82571a9cf65 100644 --- a/plugins/woocommerce/includes/class-wc-download-handler.php +++ b/plugins/woocommerce/includes/class-wc-download-handler.php @@ -522,7 +522,7 @@ class WC_Download_Handler { header( 'X-Robots-Tag: noindex, nofollow', true ); header( 'Content-Type: ' . self::get_download_content_type( $file_path ) ); header( 'Content-Description: File Transfer' ); - header( 'Content-Disposition: attachment; filename="' . $filename . '";' ); + header( 'Content-Disposition: ' . self::get_content_disposition() . '; filename="' . $filename . '";' ); header( 'Content-Transfer-Encoding: binary' ); $file_size = @filesize( $file_path ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged @@ -578,6 +578,22 @@ class WC_Download_Handler { } } + /** + * + * Get selected content disposition + * + * Defaults to attachment if `woocommerce_downloads_deliver_inline` setting is not selected. + * + * @return string Content disposition value. + */ + private static function get_content_disposition() : string { + $disposition = 'attachment'; + if ( 'yes' === get_option( 'woocommerce_downloads_deliver_inline' ) ) { + $disposition = 'inline'; + } + return $disposition; + } + /** * Read file chunked. * diff --git a/plugins/woocommerce/tests/php/includes/settings/class-wc-settings-products-test.php b/plugins/woocommerce/tests/php/includes/settings/class-wc-settings-products-test.php index 815d7207f08..800618d4c8a 100644 --- a/plugins/woocommerce/tests/php/includes/settings/class-wc-settings-products-test.php +++ b/plugins/woocommerce/tests/php/includes/settings/class-wc-settings-products-test.php @@ -141,12 +141,13 @@ class WC_Settings_Products_Test extends WC_Settings_Unit_Test_Case { $settings_ids_and_types = $this->get_ids_and_types( $settings ); $expected = array( - 'digital_download_options' => array( 'title', 'sectionend' ), - 'woocommerce_file_download_method' => 'select', - 'woocommerce_downloads_redirect_fallback_allowed' => 'checkbox', - 'woocommerce_downloads_require_login' => 'checkbox', + 'digital_download_options' => array( 'title', 'sectionend' ), + 'woocommerce_file_download_method' => 'select', + 'woocommerce_downloads_redirect_fallback_allowed' => 'checkbox', + 'woocommerce_downloads_require_login' => 'checkbox', 'woocommerce_downloads_grant_access_after_payment' => 'checkbox', - 'woocommerce_downloads_add_hash_to_filename' => 'checkbox', + 'woocommerce_downloads_add_hash_to_filename' => 'checkbox', + 'woocommerce_downloads_deliver_inline' => 'checkbox', ); $this->assertEquals( $expected, $settings_ids_and_types );