PageRenderTime 46ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-content/plugins/woocommerce-payments/vendor/woocommerce/subscriptions-core/includes/class-wcs-download-handler.php

https://gitlab.com/remyvianne/krowkaramel
PHP | 263 lines | 131 code | 45 blank | 87 comment | 25 complexity | bcb693dc2e42aeb0fe74eaa5880d52a4 MD5 | raw file
  1. <?php
  2. /**
  3. * Download Handler for WooCommerce Subscriptions
  4. *
  5. * Functions for download related things within the Subscription Extension.
  6. *
  7. * @package WooCommerce Subscriptions
  8. * @subpackage WCS_Download_Handler
  9. * @category Class
  10. * @author Prospress
  11. * @since 2.0
  12. */
  13. if ( ! defined( 'ABSPATH' ) ) {
  14. exit; // Exit if accessed directly
  15. }
  16. class WCS_Download_Handler {
  17. /**
  18. * Initialize filters and hooks for class.
  19. *
  20. * @since 2.0
  21. */
  22. public static function init() {
  23. add_action( 'woocommerce_grant_product_download_permissions', __CLASS__ . '::save_downloadable_product_permissions' );
  24. add_filter( 'woocommerce_get_item_downloads', __CLASS__ . '::get_item_downloads', 10, 3 );
  25. add_action( 'woocommerce_process_shop_order_meta', __CLASS__ . '::repair_permission_data', 60, 1 );
  26. add_action( 'woocommerce_admin_created_subscription', array( __CLASS__, 'grant_download_permissions' ) );
  27. add_action( 'deleted_post', __CLASS__ . '::delete_subscription_permissions' );
  28. add_action( 'woocommerce_process_product_file_download_paths', __CLASS__ . '::grant_new_file_product_permissions', 11, 3 );
  29. }
  30. /**
  31. * Save the download permissions on the individual subscriptions as well as the order. Hooked into
  32. * 'woocommerce_grant_product_download_permissions', which is strictly after the order received all the info
  33. * it needed, so we don't need to play with priorities.
  34. *
  35. * @param integer $order_id the ID of the order. At this point it is guaranteed that it has files in it and that it hasn't been granted permissions before
  36. */
  37. public static function save_downloadable_product_permissions( $order_id ) {
  38. global $wpdb;
  39. $order = wc_get_order( $order_id );
  40. if ( wcs_order_contains_subscription( $order, 'any' ) ) {
  41. $subscriptions = wcs_get_subscriptions_for_order( $order, array( 'order_type' => array( 'any' ) ) );
  42. } else {
  43. return;
  44. }
  45. foreach ( $subscriptions as $subscription ) {
  46. if ( sizeof( $subscription->get_items() ) > 0 ) {
  47. foreach ( $subscription->get_items() as $item ) {
  48. $_product = $item->get_product();
  49. if ( $_product && $_product->exists() && $_product->is_downloadable() ) {
  50. $downloads = wcs_get_objects_property( $_product, 'downloads' );
  51. $product_id = wcs_get_canonical_product_id( $item );
  52. foreach ( array_keys( $downloads ) as $download_id ) {
  53. // grant access on subscription if it does not already exist
  54. 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 ) ) ) {
  55. wc_downloadable_file_permission( $download_id, $product_id, $subscription, $item['qty'] );
  56. }
  57. self::revoke_downloadable_file_permission( $product_id, $order_id, $order->get_user_id() );
  58. }
  59. }
  60. }
  61. }
  62. update_post_meta( $subscription->get_id(), '_download_permissions_granted', 1 );
  63. }
  64. }
  65. /**
  66. * Revokes download permissions from permissions table if a file has permissions on a subscription. If a product has
  67. * multiple files, all permissions will be revoked from the original order.
  68. *
  69. * @param int $product_id the ID for the product (the downloadable file)
  70. * @param int $order_id the ID for the original order
  71. * @param int $user_id the user we're removing the permissions from
  72. * @return boolean true on success, false on error
  73. */
  74. public static function revoke_downloadable_file_permission( $product_id, $order_id, $user_id ) {
  75. global $wpdb;
  76. $table = $wpdb->prefix . 'woocommerce_downloadable_product_permissions';
  77. $where = array(
  78. 'product_id' => $product_id,
  79. 'order_id' => $order_id,
  80. 'user_id' => $user_id,
  81. );
  82. $format = array( '%d', '%d', '%d' );
  83. return $wpdb->delete( $table, $where, $format );
  84. }
  85. /**
  86. * WooCommerce's function receives the original order ID, the item and the list of files. This does not work for
  87. * download permissions stored on the subscription rather than the original order as the URL would have the wrong order
  88. * key. This function takes the same parameters, but queries the database again for download ids belonging to all the
  89. * subscriptions that were in the original order. Then for all subscriptions, it checks all items, and if the item
  90. * passed in here is in that subscription, it creates the correct download link to be passsed to the email.
  91. *
  92. * @param array $files List of files already included in the list
  93. * @param array $item An item (you get it by doing $order->get_items())
  94. * @param WC_Order $order The original order
  95. * @return array List of files with correct download urls
  96. */
  97. public static function get_item_downloads( $files, $item, $order ) {
  98. global $wpdb;
  99. if ( wcs_order_contains_subscription( $order, array( 'parent', 'renewal', 'switch' ) ) ) {
  100. $subscriptions = wcs_get_subscriptions_for_order( $order, array( 'order_type' => array( 'parent', 'renewal', 'switch' ) ) );
  101. } else {
  102. return $files;
  103. }
  104. $product_id = wcs_get_canonical_product_id( $item );
  105. foreach ( $subscriptions as $subscription ) {
  106. foreach ( $subscription->get_items() as $subscription_item ) {
  107. if ( wcs_get_canonical_product_id( $subscription_item ) === $product_id ) {
  108. if ( is_callable( array( $subscription_item, 'get_item_downloads' ) ) ) { // WC 3.0+
  109. $files = $subscription_item->get_item_downloads( $subscription_item );
  110. } else { // WC < 3.0
  111. $files = $subscription->get_item_downloads( $subscription_item );
  112. }
  113. }
  114. }
  115. }
  116. return $files;
  117. }
  118. /**
  119. * Repairs a glitch in WordPress's save function. You cannot save a null value on update, see
  120. * https://github.com/woocommerce/woocommerce/issues/7861 for more info on this.
  121. *
  122. * @param integer $post_id The ID of the subscription
  123. */
  124. public static function repair_permission_data( $post_id ) {
  125. if ( absint( $post_id ) !== $post_id ) {
  126. return;
  127. }
  128. if ( 'shop_subscription' !== get_post_type( $post_id ) ) {
  129. return;
  130. }
  131. global $wpdb;
  132. $wpdb->query( $wpdb->prepare( "
  133. UPDATE {$wpdb->prefix}woocommerce_downloadable_product_permissions
  134. SET access_expires = null
  135. WHERE order_id = %d
  136. AND access_expires = %s
  137. ", $post_id, '0000-00-00 00:00:00' ) );
  138. }
  139. /**
  140. * Gives customers access to downloadable products in a subscription.
  141. * Hooked into 'woocommerce_admin_created_subscription' to grant permissions to admin created subscriptions.
  142. *
  143. * @param WC_Subscription $subscription
  144. * @since 2.4.2
  145. */
  146. public static function grant_download_permissions( $subscription ) {
  147. wc_downloadable_product_permissions( $subscription->get_id() );
  148. }
  149. /**
  150. * Remove download permissions attached to a subscription when it is permenantly deleted.
  151. *
  152. * @since 2.0
  153. */
  154. public static function delete_subscription_permissions( $post_id ) {
  155. global $wpdb;
  156. if ( 'shop_subscription' == get_post_type( $post_id ) ) {
  157. $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE order_id = %d", $post_id ) );
  158. }
  159. }
  160. /**
  161. * Grant downloadable file access to any newly added files on any existing subscriptions
  162. * which don't have existing permissions pre WC3.0 and all subscriptions post WC3.0.
  163. *
  164. * @param int $product_id
  165. * @param int $variation_id
  166. * @param array $downloadable_files product downloadable files
  167. * @since 2.0.18
  168. */
  169. public static function grant_new_file_product_permissions( $product_id, $variation_id, $downloadable_files ) {
  170. global $wpdb;
  171. $product_id = ( $variation_id ) ? $variation_id : $product_id;
  172. $product = wc_get_product( $product_id );
  173. $existing_download_ids = array_keys( (array) wcs_get_objects_property( $product, 'downloads' ) );
  174. $downloadable_ids = array_keys( (array) $downloadable_files );
  175. $new_download_ids = array_filter( array_diff( $downloadable_ids, $existing_download_ids ) );
  176. if ( ! empty( $new_download_ids ) ) {
  177. $existing_permissions = $wpdb->get_results( $wpdb->prepare( "SELECT order_id, download_id from {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE product_id = %d", $product_id ) );
  178. $subscriptions = wcs_get_subscriptions_for_product( $product_id );
  179. // Arrange download id permissions by order id
  180. $permissions_by_order_id = array();
  181. foreach ( $existing_permissions as $permission_data ) {
  182. $permissions_by_order_id[ $permission_data->order_id ][] = $permission_data->download_id;
  183. }
  184. foreach ( $subscriptions as $subscription_id ) {
  185. // 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.
  186. if ( ! in_array( $subscription_id, array_keys( $permissions_by_order_id ) ) || false === wcs_is_woocommerce_pre( '3.0' ) ) {
  187. $subscription = wcs_get_subscription( $subscription_id );
  188. foreach ( $new_download_ids as $download_id ) {
  189. $has_permission = isset( $permissions_by_order_id[ $subscription_id ] ) && in_array( $download_id, $permissions_by_order_id[ $subscription_id ] );
  190. if ( $subscription && ! $has_permission && apply_filters( 'woocommerce_process_product_file_download_paths_grant_access_to_new_file', true, $download_id, $product_id, $subscription ) ) {
  191. wc_downloadable_file_permission( $download_id, $product_id, $subscription );
  192. }
  193. }
  194. }
  195. }
  196. }
  197. }
  198. /**
  199. * When adding new downloadable content to a subscription product, check if we don't
  200. * want to automatically add the new downloadable files to the subscription or initial and renewal orders.
  201. *
  202. * @deprecated 4.0.0
  203. *
  204. * @param bool $grant_access
  205. * @param string $download_id
  206. * @param int $product_id
  207. * @param WC_Order $order
  208. * @return bool
  209. * @since 2.0
  210. */
  211. public static function maybe_revoke_immediate_access( $grant_access, $download_id, $product_id, $order ) {
  212. wcs_deprecated_function( __METHOD__, '4.0.0', 'WCS_Drip_Downloads_Manager::maybe_revoke_immediate_access() if available' );
  213. if ( class_exists( 'WCS_Drip_Downloads_Manager' ) ) {
  214. return WCS_Drip_Downloads_Manager::maybe_revoke_immediate_access( $grant_access, $download_id, $product_id, $order );
  215. }
  216. return $grant_access;
  217. }
  218. }