Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
77.42% covered (warning)
77.42%
24 / 31
40.00% covered (danger)
40.00%
2 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
Historically_Active_Modules
77.42% covered (warning)
77.42%
24 / 31
40.00% covered (danger)
40.00%
2 / 5
16.26
0.00% covered (danger)
0.00%
0 / 1
 register_rest_endpoints
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
 permissions_callback
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 update_historically_active_jetpack_modules
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
8
 rest_trigger_historically_active_modules_update
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 queue_historically_active_jetpack_modules_update
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2/**
3 * Sets up the Historically Active Modules rest api endpoint and helper functions
4 *
5 * @package automattic/my-jetpack
6 */
7
8namespace Automattic\Jetpack\My_Jetpack;
9
10use WP_Error;
11
12/**
13 * Registers REST route for updating historically active modules
14 * and includes all helper functions for triggering an update elsewhere
15 */
16class Historically_Active_Modules {
17    public const UPDATE_HISTORICALLY_ACTIVE_JETPACK_MODULES_KEY = 'jetpack_update_historically_active_modules';
18
19    /**
20     * Register the REST API routes.
21     *
22     * @return void
23     */
24    public static function register_rest_endpoints() {
25        register_rest_route(
26            'my-jetpack/v1',
27            'site/update-historically-active-modules',
28            array(
29                'methods'             => \WP_REST_Server::EDITABLE,
30                'callback'            => __CLASS__ . '::rest_trigger_historically_active_modules_update',
31                'permission_callback' => __CLASS__ . '::permissions_callback',
32            )
33        );
34    }
35
36    /**
37     * Check user capabilities to access historically active modules.
38     *
39     * @access public
40     * @static
41     *
42     * @return true|WP_Error
43     */
44    public static function permissions_callback() {
45        return current_user_can( 'edit_posts' );
46    }
47
48    /**
49     * Update historically active Jetpack plugins
50     * Historically active is defined as the Jetpack plugins that are installed and active with the required connections
51     * This array will consist of any plugins that were active at one point in time and are still enabled on the site
52     *
53     * @return void
54     */
55    public static function update_historically_active_jetpack_modules() {
56        $historically_active_modules = \Jetpack_Options::get_option( 'historically_active_modules', array() );
57        $products                    = Products::get_products();
58        $product_classes             = Products::get_products_classes();
59
60        foreach ( $products as $product ) {
61            $product_slug = $product['slug'];
62            $status       = $product_classes[ $product_slug ]::get_status();
63            // We want to leave modules in the array if they've been active in the past
64            // and were not manually disabled by the user.
65            if ( in_array( $status, Products::$broken_module_statuses, true ) ) {
66                continue;
67            }
68
69            // If the module is active and not already in the array, add it
70            if (
71                in_array( $status, Products::$active_module_statuses, true ) &&
72                ! in_array( $product_slug, $historically_active_modules, true )
73            ) {
74                    $historically_active_modules[] = $product_slug;
75            }
76
77            // If the module has been disabled due to a manual user action,
78            // or because of a missing plan error, remove it from the array.
79            // A bundle without a plan reports needs_plan rather than module_disabled, so it goes too.
80            if (
81                in_array( $status, Products::$disabled_module_statuses, true ) ||
82                ( Products::STATUS_NEEDS_PLAN === $status && $product_classes[ $product_slug ]::is_bundle_product() )
83            ) {
84                $historically_active_modules = array_values( array_diff( $historically_active_modules, array( $product_slug ) ) );
85            }
86        }
87
88        \Jetpack_Options::update_option( 'historically_active_modules', array_unique( $historically_active_modules ) );
89    }
90
91    /**
92     * REST API endpoint to trigger an update to the historically active Jetpack modules
93     *
94     * @return WP_Error|\WP_REST_Response
95     */
96    public static function rest_trigger_historically_active_modules_update() {
97        self::update_historically_active_jetpack_modules();
98        $historically_active_modules = \Jetpack_Options::get_option( 'historically_active_modules', array() );
99        return rest_ensure_response( $historically_active_modules );
100    }
101
102    /**
103     * Set transient to queue an update to the historically active Jetpack modules on the next wp-admin load
104     *
105     * @param string $plugin The plugin that triggered the update. This will be present if the function was queued by a plugin activation.
106     *
107     * @return void
108     */
109    public static function queue_historically_active_jetpack_modules_update( $plugin = null ) {
110        $plugin_filenames = Products::get_all_plugin_filenames();
111
112        if ( ! $plugin || in_array( $plugin, $plugin_filenames, true ) ) {
113            set_transient( self::UPDATE_HISTORICALLY_ACTIVE_JETPACK_MODULES_KEY, true );
114        }
115    }
116}