array( 'any' ) ) ); } else { return; } foreach ( $subscriptions as $subscription ) { if ( sizeof( $subscription->get_items() ) > 0 ) { foreach ( $subscription->get_items() as $item ) { $_product = $subscription->get_product_from_item( $item ); if ( $_product && $_product->exists() && $_product->is_downloadable() ) { $downloads = wcs_get_objects_property( $_product, 'downloads' ); $product_id = wcs_get_canonical_product_id( $item ); foreach ( array_keys( $downloads ) as $download_id ) { // grant access on subscription if it does not already exist if ( ! $wpdb->get_var( $wpdb->prepare( "SELECT download_id FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE `order_id` = %d AND `product_id` = %d AND `download_id` = '%s'", $subscription->get_id(), $product_id, $download_id ) ) ) { wc_downloadable_file_permission( $download_id, $product_id, $subscription, $item['qty'] ); } self::revoke_downloadable_file_permission( $product_id, $order_id, $order->get_user_id() ); } } } } update_post_meta( $subscription->get_id(), '_download_permissions_granted', 1 ); } } /** * Revokes download permissions from permissions table if a file has permissions on a subscription. If a product has * multiple files, all permissions will be revoked from the original order. * * @param int $product_id the ID for the product (the downloadable file) * @param int $order_id the ID for the original order * @param int $user_id the user we're removing the permissions from * @return boolean true on success, false on error */ public static function revoke_downloadable_file_permission( $product_id, $order_id, $user_id ) { global $wpdb; $table = $wpdb->prefix . 'woocommerce_downloadable_product_permissions'; $where = array( 'product_id' => $product_id, 'order_id' => $order_id, 'user_id' => $user_id, ); $format = array( '%d', '%d', '%d' ); return $wpdb->delete( $table, $where, $format ); } /** * WooCommerce's function receives the original order ID, the item and the list of files. This does not work for * download permissions stored on the subscription rather than the original order as the URL would have the wrong order * key. This function takes the same parameters, but queries the database again for download ids belonging to all the * subscriptions that were in the original order. Then for all subscriptions, it checks all items, and if the item * passed in here is in that subscription, it creates the correct download link to be passsed to the email. * * @param array $files List of files already included in the list * @param array $item An item (you get it by doing $order->get_items()) * @param WC_Order $order The original order * @return array List of files with correct download urls */ public static function get_item_downloads( $files, $item, $order ) { global $wpdb; if ( wcs_order_contains_subscription( $order, array( 'parent', 'renewal', 'switch' ) ) ) { $subscriptions = wcs_get_subscriptions_for_order( $order, array( 'order_type' => array( 'parent', 'renewal', 'switch' ) ) ); } else { return $files; } $product_id = wcs_get_canonical_product_id( $item ); foreach ( $subscriptions as $subscription ) { foreach ( $subscription->get_items() as $subscription_item ) { if ( wcs_get_canonical_product_id( $subscription_item ) === $product_id ) { if ( is_callable( array( $subscription_item, 'get_item_downloads' ) ) ) { // WC 3.0+ $files = $subscription_item->get_item_downloads( $subscription_item ); } else { // WC < 3.0 $files = $subscription->get_item_downloads( $subscription_item ); } } } } return $files; } /** * Repairs a glitch in WordPress's save function. You cannot save a null value on update, see * https://github.com/woocommerce/woocommerce/issues/7861 for more info on this. * * @param integer $post_id The ID of the subscription */ public static function repair_permission_data( $post_id ) { if ( absint( $post_id ) !== $post_id ) { return; } if ( 'shop_subscription' !== get_post_type( $post_id ) ) { return; } global $wpdb; $wpdb->query( $wpdb->prepare( " UPDATE {$wpdb->prefix}woocommerce_downloadable_product_permissions SET access_expires = null WHERE order_id = %d AND access_expires = %s ", $post_id, '0000-00-00 00:00:00' ) ); } /** * Remove download permissions attached to a subscription when it is permenantly deleted. * * @since 2.0 */ public static function delete_subscription_permissions( $post_id ) { global $wpdb; if ( 'shop_subscription' == get_post_type( $post_id ) ) { $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE order_id = %d", $post_id ) ); } } /** * Grant downloadable file access to any newly added files on any existing subscriptions * which don't have existing permissions pre WC3.0 and all subscriptions post WC3.0. * * @param int $product_id * @param int $variation_id * @param array $downloadable_files product downloadable files * @since 2.0.18 */ public static function grant_new_file_product_permissions( $product_id, $variation_id, $downloadable_files ) { global $wpdb; $product_id = ( $variation_id ) ? $variation_id : $product_id; $product = wc_get_product( $product_id ); $existing_download_ids = array_keys( (array) wcs_get_objects_property( $product, 'downloads' ) ); $downloadable_ids = array_keys( (array) $downloadable_files ); $new_download_ids = array_filter( array_diff( $downloadable_ids, $existing_download_ids ) ); if ( ! empty( $new_download_ids ) ) { $existing_permissions = $wpdb->get_col( $wpdb->prepare( "SELECT order_id from {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE product_id = %d GROUP BY order_id", $product_id ) ); $subscriptions = wcs_get_subscriptions_for_product( $product_id ); foreach ( $subscriptions as $subscription_id ) { // Grant permissions to subscriptions which have no permissions for this product, pre WC3.0, or all subscriptions, post WC3.0, as WC doesn't grant them retrospectively anymore. if ( ! in_array( $subscription_id, $existing_permissions ) || false === WC_Subscriptions::is_woocommerce_pre( '3.0' ) ) { $subscription = wcs_get_subscription( $subscription_id ); foreach ( $new_download_ids as $download_id ) { if ( $subscription && apply_filters( 'woocommerce_process_product_file_download_paths_grant_access_to_new_file', true, $download_id, $product_id, $subscription ) ) { wc_downloadable_file_permission( $download_id, $product_id, $subscription ); } } } } } } } WCS_Download_Handler::init();