Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
64.10% covered (warning)
64.10%
25 / 39
44.44% covered (danger)
44.44%
4 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
Module_Product
67.57% covered (warning)
67.57%
25 / 37
44.44% covered (danger)
44.44%
4 / 9
43.65
0.00% covered (danger)
0.00%
0 / 1
 get_plugin_slug
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 get_plugin_filename
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 check_for_module_name
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 is_active
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 is_module_active
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
2.06
 get_feature_status
22.22% covered (danger)
22.22%
2 / 9
0.00% covered (danger)
0.00%
0 / 1
22.94
 get_status
83.33% covered (warning)
83.33%
5 / 6
0.00% covered (danger)
0.00%
0 / 1
4.07
 do_product_specific_activation
77.78% covered (warning)
77.78%
7 / 9
0.00% covered (danger)
0.00%
0 / 1
4.18
 deactivate
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
2.06
1<?php
2/**
3 * Base Module product
4 *
5 * @package my-jetpack
6 */
7
8namespace Automattic\Jetpack\My_Jetpack;
9
10use Automattic\Jetpack\Connection\Manager as Connection_Manager;
11use Jetpack;
12use WP_Error;
13
14if ( ! defined( 'ABSPATH' ) ) {
15    exit( 0 );
16}
17
18/**
19 * Class responsible for handling the Module products
20 *
21 * Module products are those that are a Jetpack module behind the scenes.
22 *
23 * They require Jetpack plugin and will then activate/deactivate a module.
24 */
25abstract class Module_Product extends Product {
26
27    /**
28     * The Jetpack module name associated with this product
29     *
30     * @var string|null
31     */
32    public static $module_name = null;
33
34    /**
35     * Get the plugin slug - ovewrite it ans return Jetpack's
36     *
37     * @return ?string
38     */
39    public static function get_plugin_slug() {
40        return self::JETPACK_PLUGIN_SLUG;
41    }
42
43    /**
44     * Get the plugin filename - ovewrite it ans return Jetpack's
45     *
46     * @return ?string
47     */
48    public static function get_plugin_filename() {
49        return self::JETPACK_PLUGIN_FILENAME;
50    }
51
52    /**
53     * Ensure that child classes define $module_name attribute
54     *
55     * @throws \Exception If required attribute is not declared in the child class.
56     * @return void
57     */
58    private static function check_for_module_name() {
59        if ( empty( static::$module_name ) ) {
60            throw new \Exception( 'Module Product classes must declare the $module_name attribute.' );
61        }
62    }
63
64    /**
65     * Checks whether the Product is active
66     *
67     * @return boolean
68     */
69    public static function is_active() {
70        return static::is_jetpack_plugin_active() && static::is_module_active();
71    }
72
73    /**
74     * Checks whether the Jetpack module is active
75     *
76     * @return bool
77     */
78    public static function is_module_active() {
79        self::check_for_module_name();
80        if ( ! class_exists( 'Jetpack' ) ) {
81            return false;
82        }
83
84        return Jetpack::is_module_active( static::$module_name );
85    }
86
87    /**
88     * Get the product status.
89     * We don't use parent::get_status() to avoid complexity.
90     *
91     * @return string Product status.
92     */
93    private static function get_feature_status() {
94        if ( ! static::is_plugin_installed() ) {
95            return Products::STATUS_PLUGIN_ABSENT;
96        }
97
98        if ( ! static::is_plugin_active() ) {
99            return Products::STATUS_INACTIVE;
100        }
101
102        if ( static::$requires_user_connection && ! ( new Connection_Manager() )->has_connected_owner() ) {
103            return Products::STATUS_USER_CONNECTION_ERROR;
104        }
105
106        if ( ! static::is_module_active() ) {
107            return Products::STATUS_MODULE_DISABLED;
108        }
109
110        return Products::STATUS_ACTIVE;
111    }
112
113    /**
114     * Gets the current status of the product
115     *
116     * @return string
117     */
118    public static function get_status() {
119        if ( static::$is_feature ) {
120            return static::get_feature_status();
121        }
122
123        $status = parent::get_status();
124        if ( Products::STATUS_INACTIVE === $status && ! static::is_module_active() ) {
125            $status = Products::STATUS_MODULE_DISABLED;
126        }
127        return $status;
128    }
129
130    /**
131     * Activates the product by installing and activating its plugin
132     *
133     * @param bool|WP_Error $plugin_activation Is the result of the top level activation actions. You probably won't do anything if it is an WP_Error.
134     * @return boolean|\WP_Error
135     */
136    public static function do_product_specific_activation( $plugin_activation ) {
137        self::check_for_module_name();
138
139        if ( is_wp_error( $plugin_activation ) ) {
140            return $plugin_activation;
141        }
142
143        if ( ! class_exists( 'Jetpack' ) ) {
144            return new WP_Error( 'plugin_activation_failed', __( 'Error activating Jetpack plugin', 'jetpack-my-jetpack' ) );
145        }
146
147        $module_activation = Jetpack::activate_module( static::$module_name, false, false );
148
149        if ( ! $module_activation ) {
150            return new WP_Error( 'module_activation_failed', __( 'Error activating Jetpack module', 'jetpack-my-jetpack' ) );
151        }
152
153        return $module_activation;
154    }
155
156    /**
157     * Deactivate the module
158     *
159     * @return boolean
160     */
161    public static function deactivate() {
162        self::check_for_module_name();
163        if ( ! class_exists( 'Jetpack' ) ) {
164            return true;
165        }
166        return Jetpack::deactivate_module( static::$module_name );
167    }
168}