mirror of
https://github.com/pronamic/woocommerce-subscriptions.git
synced 2025-10-07 01:54:05 +00:00
623 lines
24 KiB
PHP
623 lines
24 KiB
PHP
<?php
|
|
/**
|
|
* Downloadable files access policy for gifted subscriptions.
|
|
*
|
|
* @package WooCommerce Subscriptions Gifting
|
|
*/
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit; // Exit if accessed directly.
|
|
}
|
|
|
|
/**
|
|
* Properly handles permissions and access for downloadable files associated to gifted subscriptions.
|
|
*/
|
|
class WCSG_Download_Handler {
|
|
|
|
/**
|
|
* Cache of subscription download permissions.
|
|
*
|
|
* @var array
|
|
*/
|
|
private static $subscription_download_permissions = array();
|
|
|
|
/**
|
|
* Temporary cache of recipient download permissions stored before a subscription is saved.
|
|
*
|
|
* @var array
|
|
*/
|
|
private static $recipient_download_permissions = array();
|
|
|
|
/**
|
|
* Setup hooks & filters, when the class is initialised.
|
|
*/
|
|
public static function init() {
|
|
add_filter( 'woocommerce_subscription_settings', __CLASS__ . '::register_download_settings', 11, 1 );
|
|
add_filter( 'woocommerce_downloadable_file_permission_data', __CLASS__ . '::grant_recipient_download_permissions', 11 );
|
|
add_filter( 'woocommerce_get_item_downloads', __CLASS__ . '::get_item_download_links', 15, 3 );
|
|
|
|
// Download Permission Meta Box Functions.
|
|
add_action( 'woocommerce_process_shop_order_meta', __CLASS__ . '::download_permissions_meta_box_save', 10, 1 );
|
|
add_action( 'woocommerce_admin_order_data_after_order_details', __CLASS__ . '::get_download_permissions_before_meta_box', 10, 1 );
|
|
add_filter( 'woocommerce_admin_download_permissions_title', __CLASS__ . '::add_user_to_download_permission_title', 10, 3 );
|
|
|
|
// Grant access via download meta box - hooked on prior to WC_AJAX::grant_access_to_download().
|
|
add_action( 'wp_ajax_woocommerce_grant_access_to_download', __CLASS__ . '::ajax_grant_download_permission', 9 );
|
|
|
|
// Revoke access via download meta box - hooked to a custom Ajax handler in place of WC_AJAX::revoke_access_to_download().
|
|
add_action( 'wp_ajax_wcsg_revoke_access_to_download', __CLASS__ . '::ajax_revoke_download_permission' );
|
|
|
|
// Handle subscriptions created on the admin. Needs to be hooked on prior WCS_Download_Handler::grant_permissions_on_admin_created_subscription().
|
|
add_action( 'woocommerce_admin_created_subscription', array( __CLASS__, 'grant_permissions_on_admin_created_subscription' ), 1 );
|
|
|
|
// Handle recipient download permissions when the subscription's customer or recipient is changed.
|
|
add_action( 'woocommerce_before_subscription_object_save', array( __CLASS__, 'maybe_store_recipient_permissions_before_save' ) );
|
|
add_action( 'woocommerce_order_object_updated_props', array( __CLASS__, 'maybe_restore_recipient_permissions_after_save' ), 10, 2 );
|
|
add_action( 'woocommerce_subscriptions_gifting_recipient_changed', array( __CLASS__, 'maybe_grant_permissions_to_new_recipient' ), 10, 3 );
|
|
}
|
|
|
|
/**
|
|
* Gets the correct user's download links for a downloadable order item.
|
|
* If the request is from within an email, the links belonging to the email recipient are returned otherwise
|
|
* if the request is from the view subscription page use the current user id,
|
|
* otherwise the links for order's customer user are returned.
|
|
*
|
|
* @param array $files Downloadable files for the order item.
|
|
* @param array $item Order line item.
|
|
* @param object $order Order object.
|
|
* @return array $files Files.
|
|
*/
|
|
public static function get_item_download_links( $files, $item, $order ) {
|
|
$recipient_user_id = WCS_Gifting::get_recipient_user( $order );
|
|
|
|
if ( $recipient_user_id ) {
|
|
$user_id = ( wcs_is_subscription( $order ) && wcs_is_view_subscription_page() ) ? get_current_user_id() : $order->get_user_id();
|
|
$mailer = WC()->mailer();
|
|
|
|
foreach ( $mailer->emails as $email ) {
|
|
if ( isset( $email->wcsg_sending_recipient_email ) ) {
|
|
$user_id = $recipient_user_id;
|
|
break;
|
|
}
|
|
}
|
|
|
|
$files = self::get_user_downloads_for_order_item( $order, $user_id, $item );
|
|
}
|
|
return $files;
|
|
}
|
|
|
|
/**
|
|
* Grants download permissions to the recipient rather than the purchaser by default. However if the
|
|
* purchaser can download setting is selected, permissions are granted to both recipient and purchaser.
|
|
*
|
|
* @param array $data download permission data inserted into the wp_woocommerce_downloadable_product_permissions table.
|
|
* @return array $data
|
|
*/
|
|
public static function grant_recipient_download_permissions( $data ) {
|
|
|
|
$subscription = wcs_get_subscription( $data['order_id'] );
|
|
|
|
if ( $subscription && WCS_Gifting::is_gifted_subscription( $subscription ) ) {
|
|
|
|
$can_purchaser_download = ( 'yes' === get_option( WCSG_Admin::$option_prefix . '_downloadable_products', 'no' ) ) ? true : false;
|
|
|
|
if ( $can_purchaser_download ) {
|
|
remove_filter( 'woocommerce_downloadable_file_permission_data', __CLASS__ . '::grant_recipient_download_permissions', 11 );
|
|
|
|
wc_downloadable_file_permission( $data['download_id'], $data['product_id'], $subscription );
|
|
|
|
add_filter( 'woocommerce_downloadable_file_permission_data', __CLASS__ . '::grant_recipient_download_permissions', 11 );
|
|
}
|
|
|
|
$recipient_id = WCS_Gifting::get_recipient_user( $subscription );
|
|
$recipient = get_user_by( 'id', $recipient_id );
|
|
$data['user_id'] = $recipient_id;
|
|
$data['user_email'] = $recipient->user_email;
|
|
}
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* Insert Gifting download specific settings into Subscriptions settings
|
|
*
|
|
* @param array $settings Subscription's current set of settings.
|
|
* @return array $settings new settings with appended wcsg specific settings.
|
|
*/
|
|
public static function register_download_settings( $settings ) {
|
|
|
|
$insert_index = array_search( // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
|
|
array(
|
|
'type' => 'sectionend',
|
|
'id' => WCSG_Admin::$option_prefix,
|
|
),
|
|
$settings
|
|
);
|
|
|
|
array_splice(
|
|
$settings,
|
|
$insert_index,
|
|
0,
|
|
array(
|
|
array(
|
|
'name' => __( 'Downloadable Products', 'woocommerce-subscriptions' ),
|
|
'desc' => __( 'Allow both purchaser and recipient to download subscription products.', 'woocommerce-subscriptions' ),
|
|
'id' => WCSG_Admin::$option_prefix . '_downloadable_products',
|
|
'default' => 'no',
|
|
'type' => 'checkbox',
|
|
'row_class' => 'gifting-downloadable-products',
|
|
'desc_tip' => __( 'If you want both the recipient and purchaser of a subscription to have access to downloadable products.', 'woocommerce-subscriptions' ),
|
|
),
|
|
)
|
|
);
|
|
|
|
return $settings;
|
|
}
|
|
|
|
/**
|
|
* Before displaying the meta box, save an unmodified set of the download permissions so they can be used later
|
|
* when displaying user information and outputting download permission hidden fields (which needs to be done just
|
|
* once per permission).
|
|
*
|
|
* @param WC_Subscription $subscription Subscription object.
|
|
*/
|
|
public static function get_download_permissions_before_meta_box( $subscription ) {
|
|
global $wpdb;
|
|
|
|
if ( WCS_Gifting::is_gifted_subscription( $subscription ) ) {
|
|
|
|
self::$subscription_download_permissions = self::get_subscription_download_permissions( wcsg_get_objects_id( $subscription ) );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Formats the download permission title to also include information about the user the permission belongs to.
|
|
* This is to make it clear to store managers which user's permissions are being edited.
|
|
*
|
|
* We also sneak in hidden fields for the user and permission ID to make sure that we can revoke or modify
|
|
* permissions for a specific user, because WC doesn't use permission IDs and instead uses download IDs, which
|
|
* are a hash that do not take into account user ID and duplicate permissions for the same product on the same
|
|
* order for different users.
|
|
*
|
|
* @param string $download_title The download permission title displayed in order download permission meta boxes.
|
|
* @param int $product_id Product ID.
|
|
* @param int $order_id Order ID.
|
|
*/
|
|
public static function add_user_to_download_permission_title( $download_title, $product_id, $order_id ) {
|
|
|
|
$subscription = wcs_get_subscription( $order_id );
|
|
|
|
if ( WCS_Gifting::is_gifted_subscription( $subscription ) ) {
|
|
|
|
foreach ( self::$subscription_download_permissions as $index => $download ) {
|
|
if ( ! isset( $download->displayed ) ) {
|
|
?>
|
|
<input type="hidden" class="wcsg_download_permission_id" name="wcsg_download_permission_ids[<?php echo esc_attr( $index ); ?>]" value="<?php echo absint( $download->permission_id ); ?>" />
|
|
<input type="hidden" class="wcsg_download_permission_id" name="wcsg_download_user_ids[<?php echo esc_attr( $index ); ?>]" value="<?php echo absint( $download->user_id ); ?>" />
|
|
<?php
|
|
|
|
$user_role = ( WCS_Gifting::get_recipient_user( $subscription ) == $download->user_id ) ? __( 'Recipient', 'woocommerce-subscriptions' ) : __( 'Purchaser', 'woocommerce-subscriptions' ); // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
|
|
$user = get_userdata( $download->user_id );
|
|
$user_name = ucfirst( $user->first_name ) . ( ( ! empty( $user->last_name ) ) ? ' ' . ucfirst( $user->last_name ) : '' );
|
|
|
|
$download_title = $user_role . ' (' . ( empty( $user_name ) ? ucfirst( $user->display_name ) : $user_name ) . ') — ' . $download_title;
|
|
$download->displayed = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $download_title;
|
|
}
|
|
|
|
/**
|
|
* Save download permission meta box data.
|
|
*
|
|
* We need to unhook WC_Meta_Box_Order_Downloads::save() to prevent the WC save function from being called because
|
|
* it does not differentiate between duplicate permissions for the same product on the same order even when the
|
|
* permissions are for different users (and with different permission IDs). This means it would modify all
|
|
* permissions on that order for that product and set them all to be for the same user, instead of keeping
|
|
* them for the different users.
|
|
*
|
|
* @param int $subscription_id Subscription ID.
|
|
*/
|
|
public static function download_permissions_meta_box_save( $subscription_id ) {
|
|
global $wpdb;
|
|
|
|
// Post WC 3.0 WC_Meta_Box_Order_Downloads::save() no longer overrides the user ID associated with the download permissions so the contents of this function aren't necessary.
|
|
if ( ! wcsg_is_woocommerce_pre( '3.0' ) ) {
|
|
return;
|
|
}
|
|
|
|
if ( isset( $_POST['wcsg_download_permission_ids'] ) && isset( $_POST['woocommerce_meta_nonce'] ) && wp_verify_nonce( $_POST['woocommerce_meta_nonce'], 'woocommerce_save_data' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
|
|
|
|
remove_action( 'woocommerce_process_shop_order_meta', 'WC_Meta_Box_Order_Downloads::save', 30 );
|
|
|
|
// phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
|
|
$permission_ids = $_POST['wcsg_download_permission_ids'];
|
|
$user_ids = $_POST['wcsg_download_user_ids'];
|
|
$download_ids = $_POST['download_id'];
|
|
$product_ids = $_POST['product_id'];
|
|
$downloads_remaining = $_POST['downloads_remaining'];
|
|
$access_expires = $_POST['access_expires'];
|
|
// phpcs:enable
|
|
|
|
$subscription = wcs_get_subscription( $subscription_id );
|
|
|
|
foreach ( $download_ids as $index => $download_id ) {
|
|
|
|
$expiry = ( array_key_exists( $index, $access_expires ) && '' != $access_expires[ $index ] ) ? date_i18n( 'Y-m-d', strtotime( $access_expires[ $index ] ) ) : null; // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
|
|
|
|
$data = array(
|
|
'downloads_remaining' => wc_clean( $downloads_remaining[ $index ] ),
|
|
'access_expires' => $expiry,
|
|
);
|
|
|
|
$format = array( '%s', '%s' );
|
|
|
|
// if we're updating the purchaser's permissions, update the download user id and email, in case it has changed.
|
|
if ( WCS_Gifting::get_recipient_user( $subscription ) != $user_ids[ $index ] ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
|
|
$data['user_id'] = absint( $_POST['customer_user'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated
|
|
$format[] = '%d';
|
|
|
|
$data['user_email'] = wc_clean( wp_unslash( $_POST['_billing_email'] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated
|
|
$format[] = '%s';
|
|
}
|
|
|
|
$wpdb->update(
|
|
$wpdb->prefix . 'woocommerce_downloadable_product_permissions',
|
|
$data,
|
|
array(
|
|
'order_id' => $subscription_id,
|
|
'product_id' => absint( $product_ids[ $index ] ),
|
|
'download_id' => wc_clean( $download_ids[ $index ] ),
|
|
'permission_id' => $permission_ids[ $index ],
|
|
),
|
|
$format,
|
|
array( '%d', '%d', '%s', '%d' )
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get all download permissions for a subscription
|
|
*
|
|
* @param int $subscription_id Subscription ID.
|
|
* @param string $order_by Column to use inside the ORDER BY clause.
|
|
*/
|
|
private static function get_subscription_download_permissions( $subscription_id, $order_by = 'product_id' ) {
|
|
global $wpdb;
|
|
|
|
// Only allow ordering by permissions_id and product_id (because we can't sanitise $order_by with $wpdb->prepare(), we need it as a column not a string).
|
|
if ( 'permission_id' !== $order_by ) {
|
|
$order_by = 'product_id';
|
|
}
|
|
|
|
return $wpdb->get_results(
|
|
$wpdb->prepare(
|
|
"SELECT * FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE order_id = %d ORDER BY %s",
|
|
$subscription_id,
|
|
$order_by
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Grants download permissions from the edit subscription meta box grant access button.
|
|
* Outputs meta box table rows for each permission granted.
|
|
*/
|
|
public static function ajax_grant_download_permission() {
|
|
|
|
check_ajax_referer( 'grant-access', 'security' );
|
|
|
|
if ( ! current_user_can( 'edit_shop_orders' ) ) {
|
|
die( -1 );
|
|
}
|
|
|
|
global $wpdb;
|
|
|
|
$wpdb->hide_errors();
|
|
|
|
$order_id = isset( $_POST['order_id'] ) ? intval( $_POST['order_id'] ) : 0;
|
|
$product_ids = isset( $_POST['product_ids'] ) ? wp_unslash( $_POST['product_ids'] ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
|
$loop = isset( $_POST['loop'] ) ? intval( $_POST['loop'] ) : 0;
|
|
$file_counter = 0;
|
|
|
|
if ( WCS_Gifting::is_gifted_subscription( $order_id ) ) {
|
|
|
|
/** @var WC_Subscription $subscription */
|
|
$subscription = wcs_get_subscription( $order_id );
|
|
$download_permissions = self::get_subscription_download_permissions( $order_id, 'permission_id' );
|
|
$file_names = array();
|
|
$billing_email = is_callable( array( $subscription, 'get_billing_email' ) ) ? $subscription->get_billing_email() : $subscription->billing_email;
|
|
|
|
if ( ! $billing_email ) {
|
|
die();
|
|
}
|
|
|
|
if ( ! is_array( $product_ids ) ) {
|
|
$product_ids = array( $product_ids );
|
|
}
|
|
|
|
foreach ( $product_ids as $product_id ) {
|
|
/** @var WC_Product $product */
|
|
$product = wc_get_product( $product_id );
|
|
$files = is_callable( array( $product, 'get_downloads' ) ) ? $product->get_downloads() : $product->get_files();
|
|
|
|
if ( $files ) {
|
|
foreach ( $files as $download_id => $file ) {
|
|
|
|
++$file_counter;
|
|
|
|
if ( isset( $file['name'] ) ) {
|
|
$file_names[ $download_id ] = $file['name'];
|
|
} else {
|
|
// Translators: placeholder is the number of files.
|
|
$file_names[ $download_id ] = sprintf( __( 'File %d', 'woocommerce-subscriptions' ), $file_counter );
|
|
}
|
|
|
|
wc_downloadable_file_permission( $download_id, $product_id, $subscription );
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( 0 < count( $file_names ) ) {
|
|
$updated_download_permissions = self::get_subscription_download_permissions( $order_id, 'permission_id' );
|
|
$new_download_permissions = array_diff( array_keys( $updated_download_permissions ), array_keys( $download_permissions ) );
|
|
|
|
foreach ( $new_download_permissions as $new_download_permission_index ) {
|
|
|
|
++$loop;
|
|
|
|
$download = $updated_download_permissions[ $new_download_permission_index ];
|
|
$file_count = $file_names[ $download->download_id ];
|
|
|
|
self::$subscription_download_permissions[ $loop ] = $download;
|
|
|
|
if ( class_exists( 'WC_Customer_Download' ) ) {
|
|
// Post WC 3.0 the template expects a WC_Customer_Download object rather than stdClass objects.
|
|
$download = new WC_Customer_Download( $download );
|
|
}
|
|
include plugin_dir_path( WC_PLUGIN_FILE ) . 'includes/admin/meta-boxes/views/html-order-download-permission.php';
|
|
}
|
|
}
|
|
|
|
die();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* WooCommerce revokes download permissions based only on the product an order ID, that means when
|
|
* revoking downloads on a gift subscription with permissions for both the purchaser and recipient,
|
|
* it will revoke both sets of permissions instead of only the permission against which the store
|
|
* manager clicked the "Revoke Access" button.
|
|
*
|
|
* To workaround this, we add the permission ID as a hidden fields against each download permission
|
|
* with @see self::add_user_to_download_permission_title(). We then trigger a custom Ajax request
|
|
* that passes the permission ID to the server to make sure we only revoke only that permission.
|
|
*
|
|
* We also need to remove WC's handler, which is the WC_Ajax:;revoke_access_to_download() method attached
|
|
* to the 'woocommerce_revoke_access_to_download' Ajax action. To do this, we have out wcsg-admin.js file
|
|
* enqueued after WooCommerce's 'wc-admin-order-meta-boxes' script and then in our JavaScript call
|
|
* $( '.order_download_permissions' ).off() to remove WooCommerce's Ajax method.
|
|
*
|
|
* @since 7.8.0 - Originally implemented in WooCommerce Subscriptions Gifting 1.0.
|
|
*/
|
|
public static function ajax_revoke_download_permission() {
|
|
global $wpdb;
|
|
|
|
check_admin_referer( 'revoke_download_permission', 'nonce' );
|
|
|
|
if ( ! current_user_can( 'edit_shop_orders' ) ) {
|
|
die( -1 );
|
|
}
|
|
|
|
$subscription_id = isset( $_POST['post_id'] ) ? intval( $_POST['post_id'] ) : 0;
|
|
|
|
if ( WCS_Gifting::is_gifted_subscription( $subscription_id ) ) {
|
|
|
|
$permission_id = isset( $_POST['download_permission_id'] ) ? intval( $_POST['download_permission_id'] ) : 0;
|
|
|
|
if ( ! empty( $permission_id ) ) {
|
|
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE order_id = %d AND permission_id = %d", $subscription_id, $permission_id ) );
|
|
}
|
|
}
|
|
|
|
die();
|
|
}
|
|
|
|
/**
|
|
* Retrieves a user's download permissions for an order.
|
|
*
|
|
* @param WC_Order $order Order object.
|
|
* @param int $user_id User ID.
|
|
* @param array $item Order item.
|
|
*
|
|
* @return array
|
|
*/
|
|
public static function get_user_downloads_for_order_item( $order, $user_id, $item ) {
|
|
global $wpdb;
|
|
|
|
$product_id = wcs_get_canonical_product_id( $item );
|
|
|
|
$downloads = $wpdb->get_results(
|
|
$wpdb->prepare(
|
|
"SELECT *
|
|
FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions
|
|
WHERE user_id = %d
|
|
AND order_id = %d
|
|
AND product_id = %d",
|
|
$user_id,
|
|
wcsg_get_objects_id( $order ),
|
|
$product_id
|
|
)
|
|
);
|
|
|
|
$files = array();
|
|
/** @var WC_Product $product */
|
|
$product = wc_get_product( $product_id );
|
|
|
|
foreach ( $downloads as $download ) {
|
|
|
|
if ( $product->has_file( $download->download_id ) ) {
|
|
if ( wcsg_is_woocommerce_pre( '3.0' ) ) {
|
|
$files[ $download->download_id ] = $product->get_file( $download->download_id );
|
|
} else {
|
|
$customer_download = new WC_Customer_Download( $download );
|
|
/** @var WC_Product_Download $file */
|
|
$file = $product->get_file( $download->download_id );
|
|
|
|
$files[ $download->download_id ] = $file->get_data();
|
|
$files[ $download->download_id ]['downloads_remaining'] = $customer_download->get_downloads_remaining();
|
|
$files[ $download->download_id ]['access_expires'] = $customer_download->get_access_expires();
|
|
}
|
|
|
|
$files[ $download->download_id ]['download_url'] = add_query_arg(
|
|
array(
|
|
'download_file' => $product_id,
|
|
'order' => $download->order_key,
|
|
'email' => $download->user_email,
|
|
'key' => $download->download_id,
|
|
),
|
|
home_url( '/' )
|
|
);
|
|
}
|
|
}
|
|
return $files;
|
|
}
|
|
|
|
/**
|
|
* Retrieves all the user's download permissions for an order by checking
|
|
* for downloads stored on the subscriptions in the order.
|
|
*
|
|
* @param WC_Order $order Order object.
|
|
* @param int $user_id User ID.
|
|
*
|
|
* @return array
|
|
*/
|
|
public static function get_user_downloads_for_order( $order, $user_id ) {
|
|
|
|
$subscriptions = wcs_get_subscriptions_for_order( $order, array( 'order_type' => array( 'any' ) ) );
|
|
$order_downloads = array();
|
|
|
|
foreach ( $subscriptions as $subscription ) {
|
|
foreach ( $subscription->get_items() as $subscription_item ) {
|
|
$order_downloads = array_merge( $order_downloads, self::get_user_downloads_for_order_item( $subscription, $user_id, $subscription_item ) );
|
|
}
|
|
}
|
|
|
|
return $order_downloads;
|
|
}
|
|
|
|
/**
|
|
* Makes sure download permissions on newly created subscriptions (admin-side) are granted after the recipient has
|
|
* been set.
|
|
*
|
|
* @param WC_Subscription $subscription Subscription object.
|
|
* @since 7.8.0 - Originally implemented in WooCommerce Subscriptions Gifting 2.0.2.
|
|
*/
|
|
public static function grant_permissions_on_admin_created_subscription( $subscription ) {
|
|
// Prevent WC Subscriptions from granting permissions to the subscription before Gifting has had a chance
|
|
// to save the recipient information.
|
|
remove_action( current_action(), array( 'WCS_Download_Handler', 'grant_download_permissions' ) );
|
|
|
|
// Grant permissions after recipient information has been saved (which happens with priority 50).
|
|
add_action( 'woocommerce_process_shop_order_meta', 'wc_downloadable_product_permissions', 60 );
|
|
}
|
|
|
|
/**
|
|
* Stores recipient download permissions before a subscription is saved, just in case they are needed later.
|
|
*
|
|
* @param WC_Subscription $subscription Subscription object.
|
|
*
|
|
* @since 7.8.0 - Originally implemented in WooCommerce Subscriptions Gifting 2.0.2.
|
|
*/
|
|
public static function maybe_store_recipient_permissions_before_save( $subscription ) {
|
|
global $wpdb;
|
|
|
|
$recipient_user_id = WCS_Gifting::get_recipient_user( $subscription );
|
|
if ( ! $recipient_user_id ) {
|
|
return;
|
|
}
|
|
|
|
if ( isset( self::$recipient_download_permissions[ $subscription->get_id() ] ) ) {
|
|
return;
|
|
}
|
|
|
|
$data_store = WC_Data_Store::load( 'customer-download' );
|
|
self::$recipient_download_permissions[ $subscription->get_id() ] = $data_store->get_downloads(
|
|
array(
|
|
'order_id' => $subscription->get_id(),
|
|
'user_id' => $recipient_user_id,
|
|
'return' => 'ids',
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Restores recipient download permissions from cached values.
|
|
*
|
|
* @param WC_Subscription $subscription Subscription object.
|
|
*
|
|
* @since 7.8.0 - Originally implemented in WooCommerce Subscriptions Gifting 2.0.2.
|
|
*/
|
|
private static function restore_recipient_permissions( $subscription ) {
|
|
$subscription = wcs_get_subscription( $subscription );
|
|
if ( ! $subscription || empty( self::$recipient_download_permissions[ $subscription->get_id() ] ) ) {
|
|
return;
|
|
}
|
|
|
|
$recipient_user_id = WCS_Gifting::get_recipient_user( $subscription );
|
|
$recipient = $recipient_user_id ? get_user_by( 'id', $recipient_user_id ) : false;
|
|
|
|
if ( ! $recipient ) {
|
|
return;
|
|
}
|
|
|
|
foreach ( self::$recipient_download_permissions[ $subscription->get_id() ] as $permission_id ) {
|
|
$download = new WC_Customer_Download( $permission_id );
|
|
$download->set_user_id( $recipient_user_id );
|
|
$download->set_user_email( $recipient->user_email );
|
|
$download->save();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Restores previous recipient permissions when the subscription's customer changes.
|
|
* This is required because WC resets all download permissions to the new customer (effectively disabling recipient access) when such a change is made.
|
|
*
|
|
* @param WC_Order $order Order object.
|
|
* @param array $updated_props Properties that changed.
|
|
*
|
|
* @since 7.8.0 - Originally implemented in WooCommerce Subscriptions Gifting 2.0.2.
|
|
*/
|
|
public static function maybe_restore_recipient_permissions_after_save( $order, $updated_props ) {
|
|
global $wpdb;
|
|
|
|
if ( ! wcs_is_subscription( $order ) || ! array_intersect( array( 'customer_id', 'billing_email' ), $updated_props ) ) {
|
|
return;
|
|
}
|
|
|
|
self::restore_recipient_permissions( $order );
|
|
}
|
|
|
|
/**
|
|
* Grants new recipients the downloads permissions the previous recipient had.
|
|
*
|
|
* @param WC_Subscription $subscription Subscription object.
|
|
* @param int $new_recipient_id New recipient user ID.
|
|
* @param int $old_recipient_id Old recipient user ID.
|
|
*
|
|
* @since 7.8.0 - Originally implemented in WooCommerce Subscriptions Gifting 2.0.2.
|
|
*/
|
|
public static function maybe_grant_permissions_to_new_recipient( $subscription, $new_recipient_id, $old_recipient_id ) {
|
|
global $wpdb;
|
|
|
|
if ( ! $old_recipient_id || ! $new_recipient_id ) {
|
|
return;
|
|
}
|
|
|
|
self::restore_recipient_permissions( $subscription );
|
|
}
|
|
}
|