WC_Download_Handler::download_product()public staticWC 1.0

Check if we need to download a file and check validity.

Method of the class: WC_Download_Handler{}

Return

null. Nothing (null).

Usage

$result = WC_Download_Handler::download_product();

WC_Download_Handler::download_product() code WC 9.4.2

public static function download_product() {
	// phpcs:disable WordPress.Security.NonceVerification.Recommended
	$product_id = absint( $_GET['download_file'] ); // phpcs:ignore WordPress.VIP.SuperGlobalInputUsage.AccessDetected, WordPress.VIP.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
	$product    = wc_get_product( $product_id );
	$downloads  = $product ? $product->get_downloads() : array();
	$data_store = WC_Data_Store::load( 'customer-download' );

	$key = empty( $_GET['key'] ) ? '' : sanitize_text_field( wp_unslash( $_GET['key'] ) );

	if (
		! $product
		|| empty( $key )
		|| empty( $_GET['order'] )
		|| ! isset( $downloads[ $key ] )
		|| ! $downloads[ $key ]->get_enabled()
	) {
		self::download_error( __( 'Invalid download link.', 'woocommerce' ) );
	}

	// Fallback, accept email address if it's passed.
	if ( empty( $_GET['email'] ) && empty( $_GET['uid'] ) ) { // WPCS: input var ok, CSRF ok.
		self::download_error( __( 'Invalid download link.', 'woocommerce' ) );
	}
	// phpcs:enable WordPress.Security.NonceVerification.Recommended

	$order_id = wc_get_order_id_by_order_key( wc_clean( wp_unslash( $_GET['order'] ) ) ); // WPCS: input var ok, CSRF ok.
	$order    = wc_get_order( $order_id );

	if ( isset( $_GET['email'] ) ) { // WPCS: input var ok, CSRF ok.
		$email_address = wp_unslash( $_GET['email'] ); // WPCS: input var ok, CSRF ok, sanitization ok.
	} else {
		// Get email address from order to verify hash.
		$email_address = is_a( $order, 'WC_Order' ) ? $order->get_billing_email() : null;

		// Prepare email address hash.
		$email_hash = function_exists( 'hash' ) ? hash( 'sha256', $email_address ) : sha1( $email_address );

		if ( is_null( $email_address ) || ! hash_equals( wp_unslash( $_GET['uid'] ), $email_hash ) ) { // WPCS: input var ok, CSRF ok, sanitization ok.
			self::download_error( __( 'Invalid download link.', 'woocommerce' ) );
		}
	}

	$download_ids = $data_store->get_downloads(
		array(
			'user_email'  => sanitize_email( str_replace( ' ', '+', $email_address ) ),
			'order_key'   => wc_clean( wp_unslash( $_GET['order'] ) ), // WPCS: input var ok, CSRF ok.
			'product_id'  => $product_id,
			'download_id' => wc_clean( preg_replace( '/\s+/', ' ', wp_unslash( $_GET['key'] ) ) ), // WPCS: input var ok, CSRF ok, sanitization ok.
			'orderby'     => 'downloads_remaining',
			'order'       => 'DESC',
			'limit'       => 1,
			'return'      => 'ids',
		)
	);

	if ( empty( $download_ids ) ) {
		self::download_error( __( 'Invalid download link.', 'woocommerce' ) );
	}

	$download = new WC_Customer_Download( current( $download_ids ) );

	/**
	 * Filter download filepath.
	 *
	 * @since 4.0.0
	 * @param string $file_path File path.
	 * @param string $email_address Email address.
	 * @param WC_Order|bool $order Order object or false.
	 * @param WC_Product $product Product object.
	 * @param WC_Customer_Download $download Download data.
	 */
	$file_path = apply_filters(
		'woocommerce_download_product_filepath',
		$product->get_file_download_path( $download->get_download_id() ),
		$email_address,
		$order,
		$product,
		$download
	);

	$parsed_file_path = self::parse_file_path( $file_path );
	$download_range   = self::get_download_range( @filesize( $parsed_file_path['file_path'] ) );  // @codingStandardsIgnoreLine.

	self::check_order_is_valid( $download );
	if ( ! $download_range['is_range_request'] ) {
		// If the remaining download count goes to 0, allow range requests to be able to finish streaming from iOS devices.
		self::check_downloads_remaining( $download );
	}
	self::check_download_expiry( $download );
	self::check_download_login_required( $download );

	do_action(
		'woocommerce_download_product',
		$download->get_user_email(),
		$download->get_order_key(),
		$download->get_product_id(),
		$download->get_user_id(),
		$download->get_download_id(),
		$download->get_order_id()
	);
	$download->save();

	// Track the download in logs and change remaining/counts.
	$current_user_id = get_current_user_id();
	$ip_address      = WC_Geolocation::get_ip_address();

	self::track_download(
		$download,
		$current_user_id > 0 ? $current_user_id : null,
		! empty( $ip_address ) ? $ip_address : null,
		$download_range['is_range_request']
	);

	self::download( $file_path, $download->get_product_id() );
}