Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
31.03% covered (danger)
31.03%
9 / 29
42.86% covered (danger)
42.86%
3 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
Status
31.03% covered (danger)
31.03%
9 / 29
42.86% covered (danger)
42.86%
3 / 7
50.69
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 get_option_name
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 get
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 set
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 on_update
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 update_mapped_modules
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
30
 track_module_status
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace Automattic\Jetpack_Boost\Lib;
4
5use Automattic\Jetpack\WP_JS_Data_Sync\Contracts\Entry_Can_Get;
6use Automattic\Jetpack\WP_JS_Data_Sync\Contracts\Entry_Can_Set;
7use Automattic\Jetpack_Boost\Modules\Modules_Setup;
8use Automattic\Jetpack_Boost\Modules\Optimizations\Cloud_CSS\Cloud_CSS;
9use Automattic\Jetpack_Boost\Modules\Optimizations\Critical_CSS\Critical_CSS;
10
11class Status implements Entry_Can_Get, Entry_Can_Set {
12
13    /**
14     * Slug of the optimization module which is currently being toggled
15     *
16     * @var string $slug
17     */
18    protected $slug;
19
20    /**
21     * A map of modules whose status are synced.
22     *
23     * @var array[] $status_sync_map
24     */
25    protected $status_sync_map;
26
27    /**
28     * @var string $option_name
29     */
30    protected $option_name;
31
32    /**
33     * Prefix for the per-module status options.
34     */
35    const OPTION_PREFIX = 'jetpack_boost_status_';
36
37    public function __construct( $slug ) {
38        $this->slug        = $slug;
39        $this->option_name = self::get_option_name( $this->slug );
40
41        $this->status_sync_map = array(
42            Cloud_CSS::get_slug() => array(
43                Critical_CSS::get_slug(),
44            ),
45        );
46    }
47
48    /**
49     * Build the status option name for a given module slug.
50     *
51     * @param string $slug Module slug.
52     * @return string The wp_options option name storing the module's status.
53     */
54    public static function get_option_name( $slug ) {
55        return self::OPTION_PREFIX . str_replace( '_', '-', $slug );
56    }
57
58    public function get( $_fallback = false ) {
59        return get_option( $this->option_name, false );
60    }
61
62    public function set( $value ) {
63        return update_option( $this->option_name, $value );
64    }
65
66    /**
67     * Called when the module is toggled.
68     *
69     * Called by Modules and triggered by the `jetpack_ds_set` action.
70     */
71    public function on_update( $new_status ) {
72        $this->update_mapped_modules( $new_status );
73        $this->track_module_status( (bool) $new_status );
74    }
75
76    /**
77     * Update modules which are to follow the status of the current module.
78     *
79     * For example: critical-css module status should be synced with cloud-css module.
80     *
81     * @param mixed $new_status
82     * @return void
83     */
84    protected function update_mapped_modules( $new_status ) {
85        if ( ! isset( $this->status_sync_map[ $this->slug ] ) ) {
86            return;
87        }
88
89        $modules_instance = Setup::get_instance_of( Modules_Setup::class );
90
91        // The moduleInstance will be there. But check just in case.
92        if ( $modules_instance !== null ) {
93            // Remove the action temporarily to avoid infinite loop.
94            remove_action( 'jetpack_boost_module_status_updated', array( $modules_instance, 'on_module_status_update' ) );
95        }
96
97        foreach ( $this->status_sync_map[ $this->slug ] as $mapped_module_slug ) {
98            $mapped_status = new Status( $mapped_module_slug );
99            $mapped_status->set( $new_status );
100        }
101
102        // The moduleInstance will be there. But check just in case.
103        if ( $modules_instance !== null ) {
104            add_action( 'jetpack_boost_module_status_updated', array( $modules_instance, 'on_module_status_update' ), 10, 2 );
105        }
106    }
107
108    protected function track_module_status( $status ) {
109        Analytics::record_user_event(
110            'set_module_status',
111            array(
112                'module' => $this->slug,
113                'status' => $status,
114            )
115        );
116    }
117}