Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
32.00% covered (danger)
32.00%
16 / 50
50.00% covered (danger)
50.00%
4 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
WPCOM_Online_Subscription_Service
33.33% covered (danger)
33.33%
16 / 48
50.00% covered (danger)
50.00%
4 / 8
179.74
0.00% covered (danger)
0.00%
0 / 1
 available
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
3
 visitor_can_view_content
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
6
 get_subscriber_email
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 is_current_user_subscribed
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
12
 is_current_user_pending_subscriber
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
12
 user_can_view_content
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 abbreviate_subscriptions
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
7
 get_site_id
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3 * This subscription service is used when a subscriber is online
4 *
5 * @package Automattic\Jetpack\Extensions\Premium_Content
6 */
7
8namespace Automattic\Jetpack\Extensions\Premium_Content\Subscription_Service;
9
10if ( ! defined( 'ABSPATH' ) ) {
11    exit( 0 );
12}
13
14/**
15 * Class WPCOM_Offline_Subscription_Service
16 *
17 * @package Automattic\Jetpack\Extensions\Premium_Content\Subscription_Service
18 */
19class WPCOM_Online_Subscription_Service extends Jetpack_Token_Subscription_Service {
20
21    /**
22     * Is available()
23     *
24     * @return bool
25     */
26    public static function available() {
27        // Return available if the user is logged in and we are on WPCOM.
28        return defined( 'IS_WPCOM' ) && IS_WPCOM && is_user_logged_in();
29    }
30
31    /**
32     * Lookup users subscriptions for a site and determine if the user has a valid subscription to match the plan ID
33     *
34     * @param array  $valid_plan_ids .
35     * @param string $access_level .
36     *
37     * @return bool
38     */
39    public function visitor_can_view_content( $valid_plan_ids, $access_level ) {
40        include_once WP_CONTENT_DIR . '/mu-plugins/email-subscriptions/subscriptions.php';
41        $email             = wp_get_current_user()->user_email;
42        $subscriber_object = \Blog_Subscriber::get( $email );
43
44        $is_blog_subscriber = false;
45        if ( $subscriber_object ) {
46            $blog_id             = $this->get_site_id();
47            $subscription_status = \Blog_Subscription::get_subscription_status_for_blog( $subscriber_object, $blog_id );
48            $is_blog_subscriber  = 'active' === $subscription_status;
49        }
50
51        return $this->user_can_view_content( $valid_plan_ids, $access_level, $is_blog_subscriber, get_the_ID() );
52    }
53
54    /**
55     * Retrieves the email of the currently authenticated subscriber.
56     *
57     * This function checks if the current user has an active subscription. If the user is subscribed,
58     * their email is returned. Otherwise, it returns an empty string to indicate no active subscription.
59     *
60     * @return string The email address of the subscribed user or an empty string if not subscribed.
61     */
62    public function get_subscriber_email() {
63        if ( ! is_user_logged_in() ) {
64            return '';
65        }
66        return wp_get_current_user()->user_email;
67    }
68
69    /**
70     * Returns true if the current authenticated user is subscribed to the current site.
71     *
72     * @return bool
73     */
74    public function is_current_user_subscribed(): bool {
75        include_once WP_CONTENT_DIR . '/mu-plugins/email-subscriptions/subscriptions.php';
76        $email             = wp_get_current_user()->user_email;
77        $subscriber_object = \Blog_Subscriber::get( $email );
78        if ( empty( $subscriber_object ) ) {
79            return false;
80        }
81        $blog_id             = $this->get_site_id();
82        $subscription_status = \Blog_Subscription::get_subscription_status_for_blog( $subscriber_object, $blog_id );
83        if ( 'active' !== $subscription_status ) {
84            return false;
85        }
86        return true;
87    }
88
89    /**
90     * Returns true if the current authenticated user has a pending subscription to the current site.
91     *
92     * @return bool
93     */
94    public function is_current_user_pending_subscriber(): bool {
95        include_once WP_CONTENT_DIR . '/mu-plugins/email-subscriptions/subscriptions.php';
96        $email             = wp_get_current_user()->user_email;
97        $subscriber_object = \Blog_Subscriber::get( $email );
98        if ( empty( $subscriber_object ) ) {
99            return false;
100        }
101        $blog_id             = $this->get_site_id();
102        $subscription_status = \Blog_Subscription::get_subscription_status_for_blog( $subscriber_object, $blog_id );
103        if ( self::BLOG_SUB_PENDING !== $subscription_status ) {
104            return false;
105        }
106        return true;
107    }
108
109    /**
110     * Lookup users subscriptions for a site and determine if the user has a valid subscription to match the plan ID
111     *
112     * @param array  $valid_plan_ids .
113     * @param string $access_level .
114     * @param bool   $is_blog_subscriber .
115     * @param int    $post_id .
116     *
117     * @return bool
118     */
119    protected function user_can_view_content( $valid_plan_ids, $access_level, $is_blog_subscriber, $post_id ) {
120        $user_id = is_user_logged_in() ? wp_get_current_user()->ID : $this->user_id;
121        /**
122         * Filter the subscriptions attached to a specific user on a given site.
123         *
124         * @since 9.4.0
125         *
126         * @param array $subscriptions Array of subscriptions.
127         * @param int   $user_id The user's ID.
128         * @param int   $site_id ID of the current site.
129         */
130        $subscriptions = apply_filters( 'earn_get_user_subscriptions_for_site_id', array(), $user_id, $this->get_site_id() );
131        // format the subscriptions so that they can be validated.
132        $subscriptions      = self::abbreviate_subscriptions( $subscriptions );
133        $is_paid_subscriber = static::validate_subscriptions( $valid_plan_ids, $subscriptions );
134
135        return $this->user_has_access( $access_level, $is_blog_subscriber, $is_paid_subscriber, $post_id, $subscriptions );
136    }
137
138    /**
139     * Report the subscriptions as an ID => [ 'end_date' => ]. mapping
140     *
141     * @param array $subscriptions_from_bd .
142     *
143     * @return array<int, object>
144     */
145    public static function abbreviate_subscriptions( $subscriptions_from_bd ) {
146        $subscriptions = array();
147        foreach ( $subscriptions_from_bd as $subscription ) {
148            // We are picking the expiry date that is the most in the future.
149            if (
150                'active' === $subscription['status'] && (
151                    ! isset( $subscriptions[ $subscription['product_id'] ] ) ||
152                    empty( $subscription['end_date'] ) || // Special condition when subscription has no expiry date - we will default to a year from now for the purposes of the token.
153                    strtotime( $subscription['end_date'] ) > strtotime( (string) $subscriptions[ $subscription['product_id'] ]->end_date )
154                )
155            ) {
156                $subscriptions[ $subscription['product_id'] ]           = new \stdClass();
157                $subscriptions[ $subscription['product_id'] ]->end_date = empty( $subscription['end_date'] ) ? gmdate( 'Y-m-d H:i:s', ( time() + 365 * 24 * 3600 ) ) : $subscription['end_date'];
158            }
159        }
160        return $subscriptions;
161    }
162
163    /**
164     * Get the site ID.
165     *
166     * @return int The site ID.
167     */
168    public function get_site_id() {
169        return get_current_blog_id();
170    }
171}