Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
85.71% covered (warning)
85.71%
36 / 42
87.50% covered (warning)
87.50%
14 / 16
CRAP
0.00% covered (danger)
0.00%
0 / 1
Scan
87.50% covered (warning)
87.50%
35 / 40
87.50% covered (warning)
87.50%
14 / 16
22.95
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%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 get_pricing_for_ui
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 get_wpcom_product_slug
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 is_active
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 do_product_specific_activation
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
 is_module_active
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 get_paid_plan_product_slugs
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 has_paid_plan_for_product
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 is_upgradable_by_bundle
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 get_post_activation_url
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 get_manage_url
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
4
 get_post_checkout_url
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2/**
3 * Scan product
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 Automattic\Jetpack\Protect_Status\Plan;
13use Automattic\Jetpack\Redirect;
14use WP_Error;
15
16if ( ! defined( 'ABSPATH' ) ) {
17    exit( 0 );
18}
19
20/**
21 * Class responsible for handling the Scan product
22 */
23class Scan extends Module_Product {
24
25    /**
26     * The product slug
27     *
28     * @var string
29     */
30    public static $slug = 'scan';
31
32    /**
33     * The Jetpack module name
34     *
35     * @var string
36     */
37    public static $module_name = 'scan';
38
39    /**
40     * The category of the product
41     *
42     * @var string
43     */
44    public static $category = 'security';
45
46    /**
47     * The feature slug that identifies the paid plan
48     *
49     * @var string
50     */
51    public static $feature_identifying_paid_plan = 'scan';
52
53    /**
54     * Get the product name
55     *
56     * @return string
57     */
58    public static function get_name() {
59        return 'Scan';
60    }
61
62    /**
63     * Get the product title
64     *
65     * @return string
66     */
67    public static function get_title() {
68        return 'Jetpack Scan';
69    }
70
71    /**
72     * Get the internationalized product description
73     *
74     * @return string
75     */
76    public static function get_description() {
77        return __( 'Around‑the‑clock web application firewall, and automated malware scanning.', 'jetpack-my-jetpack' );
78    }
79
80    /**
81     * Get the internationalized product long description
82     *
83     * @return string
84     */
85    public static function get_long_description() {
86        return __( 'Automatic scanning and one-click fixes keep your site one step ahead of security threats and malware.', 'jetpack-my-jetpack' );
87    }
88
89    /**
90     * Get the internationalized features list
91     *
92     * @return array Scan features list
93     */
94    public static function get_features() {
95        return array(
96            _x( 'Automated daily scanning', 'Scan Product Feature', 'jetpack-my-jetpack' ),
97            _x( 'One-click fixes for most issues', 'Scan Product Feature', 'jetpack-my-jetpack' ),
98            _x( 'Instant email notifications', 'Scan Product Feature', 'jetpack-my-jetpack' ),
99            _x( 'Access to latest Firewall rules', 'Scan Product Feature', 'jetpack-my-jetpack' ),
100        );
101    }
102
103    /**
104     * Get the product princing details
105     *
106     * @return array Pricing details
107     */
108    public static function get_pricing_for_ui() {
109        return array_merge(
110            array(
111                'available'          => true,
112                'wpcom_product_slug' => static::get_wpcom_product_slug(),
113            ),
114            Wpcom_Products::get_product_pricing( static::get_wpcom_product_slug() )
115        );
116    }
117
118    /**
119     * Get the WPCOM product slug used to make the purchase
120     *
121     * @return ?string
122     */
123    public static function get_wpcom_product_slug() {
124        return 'jetpack_scan';
125    }
126
127    /**
128     * Checks whether the Product is active
129     *
130     * Scan is not actually a module. Activation takes place on WPCOM. So lets consider it active if jetpack is active and has the plan.
131     *
132     * @return boolean
133     */
134    public static function is_active() {
135        return static::is_jetpack_plugin_active();
136    }
137
138    /**
139     * Activates the product by installing and activating its plugin
140     *
141     * @param bool|WP_Error $current_result Is the result of the top level activation actions. You probably won't do anything if it is an WP_Error.
142     * @return boolean|\WP_Error
143     */
144    public static function do_product_specific_activation( $current_result ) {
145
146        $product_activation = parent::do_product_specific_activation( $current_result );
147
148        if ( is_wp_error( $product_activation ) && 'module_activation_failed' === $product_activation->get_error_code() ) {
149            // Scan is not a module. There's nothing in the plugin to be activated, so it's ok to fail to activate the module.
150            $product_activation = true;
151        }
152
153        return $product_activation;
154    }
155
156    /**
157     * Checks whether the Jetpack module is active
158     *
159     * Scan is not a module. Nothing needs to be active. Let's always consider it active.
160     *
161     * @return bool
162     */
163    public static function is_module_active() {
164        return true;
165    }
166
167    /**
168     * Get the product-slugs of the paid plans for this product.
169     * (Do not include bundle plans, unless it's a bundle plan itself).
170     *
171     * @return array
172     */
173    public static function get_paid_plan_product_slugs() {
174        return array(
175            'jetpack_scan',
176            'jetpack_scan_monthly',
177            'jetpack_scan_bi_yearly',
178        );
179    }
180
181    /**
182     * Whether the site pays for Scan, by the same check as the Protect page.
183     *
184     * @return bool
185     */
186    public static function has_paid_plan_for_product() {
187        return Plan::has_required_plan();
188    }
189
190    /**
191     * Return product bundles list
192     * that supports the product.
193     *
194     * @return boolean|array Products bundle list.
195     */
196    public static function is_upgradable_by_bundle() {
197        return array( 'security', 'complete' );
198    }
199
200    /**
201     * Get the URL the user is taken after activating the product
202     *
203     * @return ?string
204     */
205    public static function get_post_activation_url() {
206        return ''; // stay in My Jetpack page.
207    }
208
209    /**
210     * Get the URL where the user manages the product
211     *
212     * @return ?string
213     */
214    public static function get_manage_url() {
215        // The Protect page lists Scan's threats.
216        // An older plugin's copy of Protect, loaded earlier in the same request, may not have this method.
217        if ( method_exists( Protect::class, 'has_protect_page' ) && Protect::has_protect_page() ) {
218            return admin_url( 'admin.php?page=jetpack-protect' );
219        }
220
221        if ( method_exists( Protect::class, 'get_scan_dashboard_url' ) ) {
222            return Protect::get_scan_dashboard_url();
223        }
224
225        return Redirect::get_url( 'my-jetpack-manage-scan' );
226    }
227
228    /**
229     * Get the URL where the user should be redirected after checkout
230     */
231    public static function get_post_checkout_url() {
232        if ( static::is_jetpack_plugin_active() ) {
233            return static::get_manage_url();
234        }
235
236        // If Jetpack is not active, it means that the user has another standalone plugin active
237        // and it follows the `Protect` plugin flow instead of `Scan` so for now it would be safe
238        // to return null and let the user go back to the My Jetpack page.
239        return null;
240    }
241}