Skip to content

Commit 416cd13

Browse files
authored
feat(content-gate): support group subscriptions access rule (#4442)
1 parent 8d25408 commit 416cd13

4 files changed

Lines changed: 318 additions & 18 deletions

File tree

includes/content-gate/class-access-rules.php

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,13 +276,50 @@ public static function get_subscription_products_options() {
276276

277277
/**
278278
* Whether the user has an active subscription for one of the given products.
279+
* Also checks if the user is a member of a group subscription with the required products.
279280
*
280281
* @param int $user_id User ID.
281282
* @param array $product_ids Required product IDs.
282283
* @return bool
283284
*/
284285
public static function has_active_subscription( $user_id, $product_ids ) {
285-
return ! empty( WooCommerce_Connection::get_active_subscriptions_for_user( $user_id, $product_ids ) );
286+
$has_subscription = false;
287+
288+
// Check user's own subscriptions.
289+
if ( ! empty( WooCommerce_Connection::get_active_subscriptions_for_user( $user_id, $product_ids ) ) ) {
290+
$has_subscription = true;
291+
}
292+
293+
// Check group subscriptions the user is a member of.
294+
if ( ! $has_subscription && function_exists( 'wcs_get_subscription' ) ) {
295+
$group_subscriptions = Group_Subscription::get_group_subscriptions_for_user( $user_id );
296+
foreach ( $group_subscriptions as $subscription ) {
297+
if ( ! $subscription || ! $subscription->has_status( WooCommerce_Connection::ACTIVE_SUBSCRIPTION_STATUSES ) ) {
298+
continue;
299+
}
300+
// If no product filter, any active group subscription grants access.
301+
if ( empty( $product_ids ) ) {
302+
$has_subscription = true;
303+
break;
304+
}
305+
// Check if the subscription has any of the required products.
306+
foreach ( $product_ids as $product_id ) {
307+
if ( $subscription->has_product( $product_id ) ) {
308+
$has_subscription = true;
309+
break 2;
310+
}
311+
}
312+
}
313+
}
314+
315+
/**
316+
* Filters whether a user has an active subscription for the given products.
317+
*
318+
* @param bool $has_subscription Whether the user has an active subscription.
319+
* @param int $user_id User ID.
320+
* @param array $product_ids Required product IDs.
321+
*/
322+
return apply_filters( 'newspack_access_rules_has_active_subscription', $has_subscription, $user_id, $product_ids );
286323
}
287324

288325
/**

includes/plugins/woocommerce-subscriptions/group-subscription/class-group-subscription.php

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class Group_Subscription {
2121
/**
2222
* Check if a subscription is a group subscription.
2323
*
24-
* @param WC_Subscription|int $subscription The subscription object or ID.
24+
* @param \WC_Subscription|int $subscription The subscription object or ID.
2525
*
2626
* @return bool Whether the subscription is a group subscription.
2727
*/
@@ -33,7 +33,7 @@ public static function is_group_subscription( $subscription ) {
3333
/**
3434
* Get the managers of a group subscription.
3535
*
36-
* @param WC_Subscription|int $subscription The subscription object or ID.
36+
* @param \WC_Subscription|int $subscription The subscription object or ID.
3737
*
3838
* @return int[] The group manager user IDs.
3939
*/
@@ -55,7 +55,7 @@ public static function get_managers( $subscription ) {
5555
/**
5656
* Get the members of a group subscription.
5757
*
58-
* @param WC_Subscription|int $subscription The subscription object or ID.
58+
* @param \WC_Subscription|int $subscription The subscription object or ID.
5959
*
6060
* @return int[] Array of user IDs for the group subscription members.
6161
*/
@@ -88,19 +88,19 @@ function( $user ) {
8888
* Filter the members of a group subscription.
8989
*
9090
* @param int[] $members Array of user IDs for group subscription members.
91-
* @param WC_Subscription $subscription The subscription object.
91+
* @param \WC_Subscription $subscription The subscription object.
9292
*/
9393
return apply_filters( 'newspack_group_subscription_members', $members, $subscription );
9494
}
9595

9696
/**
9797
* Update the member IDs for a group subscription.
9898
*
99-
* @param WC_Subscription|int $subscription The subscription object or ID.
100-
* @param int[] $members_to_add Group member user IDs to add the subscription.
101-
* @param int[] $members_to_remove Group member user IDs to remove from the subscription.
99+
* @param \WC_Subscription|int $subscription The subscription object or ID.
100+
* @param int[] $members_to_add Group member user IDs to add the subscription.
101+
* @param int[] $members_to_remove Group member user IDs to remove from the subscription.
102102
*
103-
* @return object|WP_Error Added/removed results.
103+
* @return array|\WP_Error Added/removed results.
104104
*/
105105
public static function update_members( $subscription, $members_to_add, $members_to_remove = [] ) {
106106
if ( ! function_exists( 'wcs_get_subscription' ) ) {
@@ -168,8 +168,8 @@ public static function update_members( $subscription, $members_to_add, $members_
168168
/**
169169
* Check if a user is a member or manager of a group subscription.
170170
*
171-
* @param int $user_id The user ID.
172-
* @param WC_Subscription|int $subscription The subscription object or ID.
171+
* @param int $user_id The user ID.
172+
* @param \WC_Subscription|int $subscription The subscription object or ID.
173173
*
174174
* @return bool|null Whether the user has access to the group subscription, or null if not a group subscription.
175175
*/
@@ -190,7 +190,7 @@ public static function user_is_member( $user_id, $subscription ) {
190190
*
191191
* @param bool|null $is_member Whether the user is a member or manager of the group subscription, or null if not a group subscription.
192192
* @param int $user_id The user ID.
193-
* @param WC_Subscription|int $subscription The subscription object or ID.
193+
* @param \WC_Subscription|int $subscription The subscription object or ID.
194194
*/
195195
return apply_filters( 'newspack_group_subscription_user_is_member', $is_member, $user_id, $subscription );
196196
}
@@ -202,7 +202,7 @@ public static function user_is_member( $user_id, $subscription ) {
202202
* @param int $user_id The user ID.
203203
* @param bool $ids_only If true, return only the subscription IDs instead of the subscription objects.
204204
*
205-
* @return WC_Subscription[]|int[] The group subscriptions or subscription IDs the user is a member of.
205+
* @return \WC_Subscription[]|int[] The group subscriptions or subscription IDs the user is a member of.
206206
*/
207207
public static function get_group_subscriptions_for_user( $user_id, $ids_only = false ) {
208208
if ( ! function_exists( 'wcs_get_subscription' ) ) {
@@ -220,7 +220,7 @@ public static function get_group_subscriptions_for_user( $user_id, $ids_only = f
220220
/**
221221
* Filter the group subscriptions a user is a member of.
222222
*
223-
* @param WC_Subscription[]|int[] $subscriptions The group subscriptions or subscription IDs the user is a member of.
223+
* @param \WC_Subscription[]|int[] $subscriptions The group subscriptions or subscription IDs the user is a member of.
224224
* @param int $user_id The user ID.
225225
*/
226226
return apply_filters( 'newspack_group_subscriptions_for_user', $subscriptions, $user_id );

tests/mocks/wc-mocks.php

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ public function get_email() {
9898
}
9999

100100
$orders_database = [];
101+
$subscriptions_database = [];
101102

102103
class WC_Order {
103104
public $data = [ 'items' => [] ];
@@ -154,6 +155,7 @@ class WC_Subscription {
154155
public $data = [];
155156
public $meta = [];
156157
public $orders = [];
158+
public $products = [];
157159
public function __construct( $data ) {
158160
$this->data = array_merge( $data, $this->data );
159161
if ( isset( $data['meta'] ) ) {
@@ -168,12 +170,21 @@ function( $a, $b ) {
168170
}
169171
);
170172
}
173+
if ( isset( $data['products'] ) ) {
174+
$this->products = $data['products'];
175+
}
171176
}
172177
public function get_id() {
173178
return $this->data['id'];
174179
}
175180
public function get_customer_id() {
176-
return $this->data['customer_id'];
181+
return $this->data['customer_id'] ?? null;
182+
}
183+
public function get_user_id() {
184+
return $this->data['customer_id'] ?? null;
185+
}
186+
public function has_product( $product_id ) {
187+
return in_array( $product_id, $this->products, true );
177188
}
178189
public function get_meta( $field_name ) {
179190
return isset( $this->meta[ $field_name ] ) ? $this->meta[ $field_name ] : '';
@@ -245,13 +256,40 @@ function wcs_is_subscription( $order ) {
245256
return false;
246257
}
247258
function wcs_create_subscription( $data = [] ) {
248-
return new WC_Subscription( $data );
259+
global $subscriptions_database;
260+
// Auto-generate an ID if not provided.
261+
if ( ! isset( $data['id'] ) ) {
262+
$data['id'] = count( $subscriptions_database ) + 1;
263+
}
264+
$subscription = new WC_Subscription( $data );
265+
$subscriptions_database[ $subscription->get_id() ] = $subscription;
266+
return $subscription;
267+
}
268+
function wcs_get_subscription( $subscription_id ) {
269+
global $subscriptions_database;
270+
return $subscriptions_database[ $subscription_id ] ?? null;
249271
}
250272
function wcs_get_subscriptions_for_order( $order ) {
251273
return [];
252274
}
253-
function wcs_get_users_subscriptions( $order ) {
254-
return [];
275+
function wcs_get_users_subscriptions( $user_id ) {
276+
global $subscriptions_database;
277+
$user_subscriptions = [];
278+
foreach ( $subscriptions_database as $id => $subscription ) {
279+
if ( $subscription->get_customer_id() === $user_id ) {
280+
$user_subscriptions[ $id ] = $subscription;
281+
}
282+
}
283+
return $user_subscriptions;
284+
}
285+
function wcs_get_canonical_product_id( $item ) {
286+
return null;
287+
}
288+
function wc_string_to_bool( $string ) {
289+
return is_bool( $string ) ? $string : ( 'yes' === strtolower( $string ) || '1' === $string || 'true' === strtolower( $string ) );
290+
}
291+
function wc_bool_to_string( $bool ) {
292+
return $bool ? 'yes' : 'no';
255293
}
256294
function wc_get_orders( $args ) {
257295
global $orders_database;

0 commit comments

Comments
 (0)