From e8eb000733eebbedeebfcc2ed2610299645a3514 Mon Sep 17 00:00:00 2001 From: Vedanshu Jain Date: Thu, 25 Aug 2022 23:33:03 +0530 Subject: [PATCH] Add inline file delivery to WC_Download_Handler (#31145) Add inline file delivery to WC_Download_Handler Create a new setting option for inline file delivery for downloadable products. In the Download Handler create a new method for the new setting as well as a method for returning the proper headers to deliver files inline. Resolves: #28410 * Update Content Type of inline delivered files * Update Downloaded file name * Change content-disposition to be a checkbox Since inline-delivery works with multiple download methods * Document function * Add new setting for test, see #31145. * Better setting wording and remove typo comment. * Address pr feedback. * Add changelog. * Rephrase the settings to make it more clear. * More rephrasing. Co-authored-by: Matthew Caldwell --- .../changelog/allow-inline-downloads | 4 ++++ .../settings/class-wc-settings-products.php | 10 ++++++++++ .../includes/class-wc-download-handler.php | 18 +++++++++++++++++- .../class-wc-settings-products-test.php | 11 ++++++----- 4 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 plugins/woocommerce/changelog/allow-inline-downloads 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 );