Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
58.51% covered (warning)
58.51%
55 / 94
73.33% covered (warning)
73.33%
11 / 15
CRAP
0.00% covered (danger)
0.00%
0 / 1
Complete
58.70% covered (warning)
58.70%
54 / 92
73.33% covered (warning)
73.33%
11 / 15
115.46
0.00% covered (danger)
0.00%
0 / 1
 get_name
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 get_title
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 get_description
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 get_long_description
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 get_features
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
1
 get_pricing_for_ui
71.43% covered (warning)
71.43%
10 / 14
0.00% covered (danger)
0.00%
0 / 1
3.21
 get_wpcom_product_slug
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 is_module_active
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 do_product_specific_activation
0.00% covered (danger)
0.00%
0 / 31
0.00% covered (danger)
0.00%
0 / 1
156
 is_active
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 has_required_plan
75.00% covered (warning)
75.00%
6 / 8
0.00% covered (danger)
0.00%
0 / 1
6.56
 get_paid_plan_product_slugs
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 is_bundle_product
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 get_supported_products
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
1
 get_manage_url
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3 * Complete plan
4 *
5 * @package my-jetpack
6 */
7
8namespace Automattic\Jetpack\My_Jetpack\Products;
9
10use Automattic\Jetpack\My_Jetpack\Module_Product;
11use Automattic\Jetpack\My_Jetpack\Wpcom_Products;
12use WP_Error;
13
14if ( ! defined( 'ABSPATH' ) ) {
15    exit( 0 );
16}
17
18/**
19 * Class responsible for handling the Complete plan
20 */
21class Complete extends Module_Product {
22
23    /**
24     * The product slug
25     *
26     * @var string
27     */
28    public static $slug = 'complete';
29
30    /**
31     * The Jetpack module name
32     *
33     * @var string
34     */
35    public static $module_name = 'complete';
36
37    /**
38     * Get the product name
39     *
40     * @return string
41     */
42    public static function get_name() {
43        return 'Complete Bundle';
44    }
45
46    /**
47     * Get the product title
48     *
49     * @return string
50     */
51    public static function get_title() {
52        return 'Jetpack Complete';
53    }
54
55    /**
56     * Get the internationalized product description
57     *
58     * @return string
59     */
60    public static function get_description() {
61        return __( 'The ultimate tool kit for best-in-class websites.', 'jetpack-my-jetpack' );
62    }
63
64    /**
65     * Get the internationalized product description
66     *
67     * @return string
68     */
69    public static function get_long_description() {
70        return __( 'Get the full Jetpack suite with real-time security tools, improved site performance, and tools to grow your business.', 'jetpack-my-jetpack' );
71    }
72
73    /**
74     * Get the internationalized features list
75     * Most of these are not translated as they are product names
76     *
77     * @return array Complete features list
78     */
79    public static function get_features() {
80        return array(
81            'VaultPress Backup',
82            'Scan',
83            'Akismet Anti-spam',
84            'VideoPress',
85            'Boost',
86            'Social',
87            'Search',
88            'AI Assistant',
89            _x( 'Stats (100K site views, upgradeable)', 'Complete Product Feature', 'jetpack-my-jetpack' ),
90            _x( 'CRM Entrepreneur', 'Complete Product Feature', 'jetpack-my-jetpack' ),
91            _x( 'Newsletter and monetization tools', 'Complete Product Feature', 'jetpack-my-jetpack' ),
92        );
93    }
94
95    /**
96     * Get the product pricing details
97     *
98     * @return array Pricing details
99     */
100    public static function get_pricing_for_ui() {
101        if ( empty( Pro::get_pricing_for_ui()['catalog_available'] ) ) {
102            return array_merge(
103                array(
104                    'available'          => false !== ( Wpcom_Products::get_product( static::get_wpcom_product_slug() )->available ?? null ),
105                    'wpcom_product_slug' => static::get_wpcom_product_slug(),
106                ),
107                Wpcom_Products::get_product_pricing( static::get_wpcom_product_slug() )
108            );
109        }
110        if ( ! method_exists( static::class, 'get_bundle_pricing' ) ) {
111            return array(
112                'available'          => false,
113                'wpcom_product_slug' => static::get_wpcom_product_slug(),
114            );
115        }
116        return static::get_bundle_pricing( static::get_paid_plan_product_slugs() );
117    }
118
119    /**
120     * Get the WPCOM product slug used to make the purchase
121     *
122     * @return string
123     */
124    public static function get_wpcom_product_slug() {
125        return 'jetpack_complete';
126    }
127
128    /**
129     * Checks whether the Jetpack module is active
130     *
131     * This is a bundle and not a product. We should not use this information for anything
132     *
133     * @return bool
134     */
135    public static function is_module_active() {
136        return false;
137    }
138
139    /**
140     * Activates the product by installing and activating its plugin
141     *
142     * @param WP_Error|bool $current_result Is the result of the top level activation actions. You probably won't do anything if it is an WP_Error.
143     * @return bool|\WP_Error
144     */
145    public static function do_product_specific_activation( $current_result ) {
146        $product_activation = parent::do_product_specific_activation( $current_result );
147
148        // A bundle is not a module. There's nothing in the plugin to be activated, so it's ok to fail to activate the module.
149        if ( is_wp_error( $product_activation ) && 'module_activation_failed' === $product_activation->get_error_code() ) {
150            return $product_activation;
151        }
152
153        // At this point, Jetpack plugin is installed. Let's activate each individual product.
154        $activation = Social::activate();
155        if ( is_wp_error( $activation ) ) {
156            return $activation;
157        }
158
159        $activation = Stats::activate();
160        if ( is_wp_error( $activation ) ) {
161            return $activation;
162        }
163
164        $activation = Anti_Spam::activate();
165        if ( is_wp_error( $activation ) ) {
166            return $activation;
167        }
168
169        $activation = Backup::activate();
170        if ( is_wp_error( $activation ) ) {
171            return $activation;
172        }
173
174        $activation = Scan::activate();
175        if ( is_wp_error( $activation ) ) {
176            return $activation;
177        }
178
179        $activation = Boost::activate();
180        if ( is_wp_error( $activation ) ) {
181            return $activation;
182        }
183
184        $activation = CRM::activate();
185        if ( is_wp_error( $activation ) ) {
186            return $activation;
187        }
188
189        $activation = Search::activate();
190        if ( is_wp_error( $activation ) ) {
191            return $activation;
192        }
193
194        $activation = VideoPress::activate();
195        if ( is_wp_error( $activation ) ) {
196            return $activation;
197        }
198
199        return $activation;
200    }
201
202    /**
203     * Checks whether the Product is active
204     *
205     * Security is a bundle and not a module. Activation takes place on WPCOM. So lets consider it active if jetpack is active and has the plan.
206     *
207     * @return boolean
208     */
209    public static function is_active() {
210        return static::is_jetpack_plugin_active() && static::has_required_plan();
211    }
212
213    /**
214     * Checks whether the current plan (or purchases) of the site already supports the product
215     *
216     * @return boolean
217     */
218    public static function has_required_plan() {
219        $purchases_data = Wpcom_Products::get_site_current_purchases();
220        if ( is_wp_error( $purchases_data ) ) {
221            return false;
222        }
223        if ( is_array( $purchases_data ) && ! empty( $purchases_data ) ) {
224            foreach ( $purchases_data as $purchase ) {
225                if ( str_starts_with( $purchase->product_slug, 'jetpack_complete' ) ) {
226                    return true;
227                }
228            }
229        }
230        return false;
231    }
232
233    /**
234     * Get the product-slugs of the paid plans for this product.
235     * (Do not include bundle plans, unless it's a bundle plan itself).
236     *
237     * @return array
238     */
239    public static function get_paid_plan_product_slugs() {
240        return array(
241            'jetpack_complete',
242            'jetpack_complete_bi_yearly',
243            'jetpack_complete_monthly',
244        );
245    }
246
247    /**
248     * Checks whether product is a bundle.
249     *
250     * @return boolean True
251     */
252    public static function is_bundle_product() {
253        return true;
254    }
255
256    /**
257     * Return all the products it contains.
258     *
259     * @return array Product slugs
260     */
261    public static function get_supported_products() {
262        return array(
263            'anti-spam',
264            'backup',
265            'boost',
266            'crm',
267            'scan',
268            'search',
269            'social',
270            'stats',
271            'videopress',
272            'jetpack-ai',
273        );
274    }
275
276    /**
277     * Get the URL where the user manages the product
278     *
279     * @return ?string
280     */
281    public static function get_manage_url() {
282        return '';
283    }
284}