Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
53.57% covered (warning)
53.57%
15 / 28
75.00% covered (warning)
75.00%
3 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
Jetpack_Protect_Dashboard_Feature_Flags
60.00% covered (warning)
60.00%
15 / 25
75.00% covered (warning)
75.00%
3 / 4
21.22
0.00% covered (danger)
0.00%
0 / 1
 register
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
2
 is_protect_plugin_active
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 filter_available_modules
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
5
 filter_default_modules
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
5
1<?php
2/**
3 * Protect dashboard feature flags.
4 *
5 * @package automattic/jetpack
6 */
7
8use Automattic\Jetpack\Constants;
9use Automattic\Jetpack\Feature_Flags\Feature_Flags;
10use Automattic\Jetpack\Status\Host;
11
12if ( ! defined( 'ABSPATH' ) ) {
13    exit( 0 );
14}
15
16/**
17 * Registers the flag that gates the `protect-dashboard` module, and hides the module while the Jetpack Protect plugin is active.
18 *
19 * @since 16.4
20 */
21class Jetpack_Protect_Dashboard_Feature_Flags {
22
23    const DASHBOARD = 'jetpack-protect-dashboard';
24
25    const MODULE = 'protect-dashboard';
26
27    /**
28     * Set while computing defaults as if the Jetpack Protect plugin were not active.
29     *
30     * @var bool
31     */
32    private static $ignore_protect_plugin = false;
33
34    /**
35     * Register the flag and the module filters.
36     *
37     * @return void
38     */
39    public static function register() {
40        Feature_Flags::register(
41            self::DASHBOARD,
42            array(
43                'default'     => true,
44                'description' => 'Make the Protect dashboard module available, which replaces the Protect page, including the Jetpack Protect plugin\'s. Not for sites using that plugin until the new page matches it.',
45                'owner'       => 'jetpack',
46            )
47        );
48
49        add_filter( 'jetpack_get_available_modules', array( __CLASS__, 'filter_available_modules' ) );
50        add_filter( 'jetpack_get_default_modules', array( __CLASS__, 'filter_default_modules' ), 10, 5 );
51    }
52
53    /**
54     * Whether the Jetpack Protect plugin is active, whose own page the module would take over until JETPACK-3062.
55     *
56     * @return bool
57     */
58    public static function is_protect_plugin_active() {
59        return Constants::is_defined( 'JETPACK_PROTECT_VERSION' );
60    }
61
62    /**
63     * Drop the module from the available list while the flag is off, which also keeps it from loading.
64     *
65     * WordPress.com sites keep their current security pages until JETPACK-3035, so it stays off there too, as it does
66     * while the Jetpack Protect plugin is active. Jetpack keeps an unavailable module in its stored active list.
67     *
68     * @param array $modules Available modules, keyed by slug.
69     * @return array
70     */
71    public static function filter_available_modules( $modules ) {
72        if (
73            ! Feature_Flags::is_enabled( self::DASHBOARD )
74            || ( new Host() )->is_wpcom_platform()
75            || ( ! self::$ignore_protect_plugin && self::is_protect_plugin_active() )
76        ) {
77            unset( $modules[ self::MODULE ] );
78        }
79        return $modules;
80    }
81
82    /**
83     * Keep the module a default while the Jetpack Protect plugin hides it, so the page appears once that plugin is gone.
84     *
85     * @param array       $modules                  Default module slugs.
86     * @param bool|string $min_version              Only modules introduced after this version.
87     * @param bool|string $max_version              Only modules introduced in or before this version.
88     * @param bool|null   $requires_connection      Only modules that do, or don't, require a connection.
89     * @param bool|null   $requires_user_connection Only modules that do, or don't, require a user connection.
90     * @return array
91     */
92    public static function filter_default_modules( $modules, $min_version = false, $max_version = false, $requires_connection = null, $requires_user_connection = null ) {
93        if ( self::$ignore_protect_plugin || ! self::is_protect_plugin_active() || in_array( self::MODULE, $modules, true ) ) {
94            return $modules;
95        }
96
97        $defaults                    = array();
98        self::$ignore_protect_plugin = true;
99        try {
100            $defaults = Jetpack::get_default_modules( $min_version, $max_version, $requires_connection, $requires_user_connection );
101        } finally {
102            self::$ignore_protect_plugin = false;
103        }
104
105        if ( in_array( self::MODULE, $defaults, true ) ) {
106            $modules[] = self::MODULE;
107        }
108        return $modules;
109    }
110}
111
112Jetpack_Protect_Dashboard_Feature_Flags::register();