Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
84.21% covered (warning)
84.21%
32 / 38
87.50% covered (warning)
87.50%
14 / 16
CRAP
0.00% covered (danger)
0.00%
0 / 1
Scan
86.11% covered (warning)
86.11%
31 / 36
87.50% covered (warning)
87.50%
14 / 16
24.42
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%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 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        // Consumers match by substring, so the prefix covers every Scan product. An older Protect Status may lack it.
175        return array( defined( Plan::class . '::SCAN_PRODUCT_PREFIX' ) ? Plan::SCAN_PRODUCT_PREFIX : 'jetpack_scan' );
176    }
177
178    /**
179     * Whether the site pays for Scan, by the same check as the Protect page.
180     *
181     * @return bool
182     */
183    public static function has_paid_plan_for_product() {
184        return Plan::has_required_plan();
185    }
186
187    /**
188     * Return product bundles list
189     * that supports the product.
190     *
191     * @return boolean|array Products bundle list.
192     */
193    public static function is_upgradable_by_bundle() {
194        return array( 'security', 'complete' );
195    }
196
197    /**
198     * Get the URL the user is taken after activating the product
199     *
200     * @return ?string
201     */
202    public static function get_post_activation_url() {
203        return ''; // stay in My Jetpack page.
204    }
205
206    /**
207     * Get the URL where the user manages the product
208     *
209     * @return ?string
210     */
211    public static function get_manage_url() {
212        // The Protect page lists Scan's threats.
213        // An older plugin's copy of Protect, loaded earlier in the same request, may not have this method.
214        if ( method_exists( Protect::class, 'has_protect_page' ) && Protect::has_protect_page() ) {
215            return admin_url( 'admin.php?page=jetpack-protect' );
216        }
217
218        if ( method_exists( Protect::class, 'get_scan_dashboard_url' ) ) {
219            return Protect::get_scan_dashboard_url();
220        }
221
222        return Redirect::get_url( 'my-jetpack-manage-scan' );
223    }
224
225    /**
226     * Get the URL where the user should be redirected after checkout
227     */
228    public static function get_post_checkout_url() {
229        if ( static::is_jetpack_plugin_active() ) {
230            return static::get_manage_url();
231        }
232
233        // If Jetpack is not active, it means that the user has another standalone plugin active
234        // and it follows the `Protect` plugin flow instead of `Scan` so for now it would be safe
235        // to return null and let the user go back to the My Jetpack page.
236        return null;
237    }
238}