Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 121
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
Jetpack_Newsletter_Dashboard_Widget
0.00% covered (danger)
0.00%
0 / 117
0.00% covered (danger)
0.00%
0 / 5
812
0.00% covered (danger)
0.00%
0 / 1
 init
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 get_config_data
0.00% covered (danger)
0.00%
0 / 39
0.00% covered (danger)
0.00%
0 / 1
210
 wp_dashboard_setup
0.00% covered (danger)
0.00%
0 / 24
0.00% covered (danger)
0.00%
0 / 1
20
 render
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 load_admin_scripts
0.00% covered (danger)
0.00%
0 / 47
0.00% covered (danger)
0.00%
0 / 1
56
1<?php
2/**
3 * Jetpack Newsletter Dashboard Widget.
4 *
5 * @package jetpack
6 */
7
8use Automattic\Jetpack\Connection\Client;
9use Automattic\Jetpack\Modules;
10
11/**
12 * Class that adds the Jetpack Newsletter Dashboard Widget to the WordPress admin dashboard.
13 */
14class Jetpack_Newsletter_Dashboard_Widget {
15    /**
16     * Indicates whether the class initialized or not.
17     *
18     * @var bool
19     */
20    private static $initialized = false;
21
22    /**
23     * The Widget ID.
24     *
25     * @var string
26     */
27    private static $widget_id = 'jetpack_newsletter_dashboard_widget';
28
29    /**
30     * Initialize the class by calling the setup static function.
31     *
32     * @return void
33     */
34    public static function init() {
35        if ( ! self::$initialized ) {
36            self::$initialized = true;
37            self::wp_dashboard_setup();
38        }
39    }
40
41    /**
42     * Get the config data for the Jetpack Newsletter widget.
43     *
44     * @return array
45     */
46    public static function get_config_data() {
47        $config_data = array(
48            'emailSubscribers'       => 0,
49            'paidSubscribers'        => 0,
50            'allSubscribers'         => 0,
51            'subscriberTotalsByDate' => array(),
52            'isStatsModuleActive'    => false,
53            'showHeader'             => false,
54            'showChart'              => false,
55            'isWidgetVisible'        => false,
56            'newsletterSettingsUrl'  => \Automattic\Jetpack\Newsletter\Urls::get_newsletter_settings_url(),
57        );
58
59        if ( Jetpack::is_connection_ready() ) {
60            $site_id  = Jetpack_Options::get_option( 'id' );
61            $api_path = sprintf( '/sites/%d/subscribers/stats', $site_id );
62            $response = Client::wpcom_json_api_request_as_blog(
63                $api_path,
64                '2',
65                array(),
66                null,
67                'wpcom'
68            );
69
70            if ( 200 === wp_remote_retrieve_response_code( $response ) ) {
71                $subscriber_counts = json_decode( wp_remote_retrieve_body( $response ), true );
72                if ( isset( $subscriber_counts['counts']['email_subscribers'] ) ) {
73                    $config_data['emailSubscribers'] = (int) $subscriber_counts['counts']['email_subscribers'];
74                }
75
76                if ( isset( $subscriber_counts['counts']['paid_subscribers'] ) ) {
77                    $config_data['paidSubscribers'] = (int) $subscriber_counts['counts']['paid_subscribers'];
78                }
79
80                if ( isset( $subscriber_counts['counts']['all_subscribers'] ) ) {
81                    $config_data['allSubscribers'] = (int) $subscriber_counts['counts']['all_subscribers'];
82                }
83
84                if ( isset( $subscriber_counts['aggregate'] ) ) {
85                    $config_data['subscriberTotalsByDate'] = $subscriber_counts['aggregate'];
86                }
87            }
88
89            $config_data['isStatsModuleActive'] = ( new Modules() )->is_active( 'stats' );
90
91            $config_data['showHeader'] = $config_data['isStatsModuleActive'] && ( $config_data['allSubscribers'] > 0 || $config_data['paidSubscribers'] > 0 );
92            foreach ( $config_data['subscriberTotalsByDate'] as $day ) {
93                if ( $day && ( $day['all'] >= 5 || $day['paid'] > 0 ) ) {
94                    $config_data['showChart'] = true;
95                    break;
96                }
97            }
98
99            $config_data['isWidgetVisible'] = $config_data['showHeader'] || $config_data['showChart'];
100        }
101
102        return $config_data;
103    }
104
105    /**
106     * Sets up the Jetpack Newsletter widget in the WordPress admin dashboard.
107     */
108    public static function wp_dashboard_setup() {
109        // Do not show the widget to non-admins.
110        if ( ! current_user_can( 'manage_options' ) ) {
111            return;
112        }
113
114        if ( Jetpack::is_connection_ready() ) {
115            $config_data = static::get_config_data();
116
117            if ( ! $config_data['isWidgetVisible'] ) {
118                return;
119            }
120
121            static::load_admin_scripts(
122                'jp-newsletter-widget',
123                'newsletter-widget',
124                array(
125                    'config_variable_name' => 'jetpackNewsletterWidgetConfigData',
126                    'config_data'          => $config_data,
127                    'load_minified_js'     => false,
128                )
129            );
130
131            wp_add_dashboard_widget(
132                self::$widget_id,
133                /** "Newsletter" is a product name, do not translate. */
134                'Jetpack Newsletter',
135                array( static::class, 'render' ),
136                // @phan-suppress-next-line PhanTypeMismatchArgumentProbablyReal -- Core should ideally document null for no-callback arg. https://core.trac.wordpress.org/ticket/52539.
137                null,
138                array(),
139                'side',
140                'high'
141            );
142        }
143    }
144
145    /**
146     * Render the Jetpack Newsletter widget.
147     *
148     * @return void
149     */
150    public static function render() {
151        ?>
152        <div id="wpcom">
153            <div id="newsletter-widget-app"></div>
154        </div>
155        <?php
156    }
157
158    /**
159     * Load the admin scripts for the Jetpack Newsletter widget.
160     *
161     * @param string $asset_handle The handle of the asset.
162     * @param string $asset_name The name of the asset.
163     * @param array  $options The options for the asset.
164     * @return void
165     */
166    public static function load_admin_scripts( $asset_handle, $asset_name, $options = array() ) {
167        $default_options = array(
168            'config_data'          => array(),
169            'config_variable_name' => 'configData',
170            'enqueue_css'          => true,
171            'load_minified_js'     => true,
172        );
173        $options         = wp_parse_args( $options, $default_options );
174
175        // Get the asset file path
176        $asset_path = JETPACK__PLUGIN_DIR . '_inc/build/' . $asset_name . '.min.asset.php';
177
178        // Get dependencies and version from asset file
179        $dependencies = array();
180        $version      = JETPACK__VERSION;
181
182        if ( file_exists( $asset_path ) ) {
183            $asset        = require $asset_path;
184            $dependencies = $asset['dependencies'];
185            $version      = $asset['version'];
186        }
187
188        $file_extension = '.min.js';
189        if ( ! $options['load_minified_js'] ) {
190            $file_extension = '.js';
191        }
192        // Register and enqueue the script
193        wp_register_script(
194            $asset_handle,
195            plugins_url( '_inc/build/' . $asset_name . $file_extension, JETPACK__PLUGIN_FILE ),
196            $dependencies,
197            $version,
198            true
199        );
200        wp_enqueue_script( $asset_handle );
201        if ( in_array( 'wp-i18n', $dependencies, true ) ) {
202            wp_set_script_translations( $asset_handle, 'jetpack' );
203        }
204
205        // Enqueue the CSS if enabled
206        if ( $options['enqueue_css'] ) {
207            wp_enqueue_style(
208                $asset_handle,
209                plugins_url( '_inc/build/' . $asset_name . '.css', JETPACK__PLUGIN_FILE ),
210                array(),
211                $version
212            );
213
214            // Enqueue RTL stylesheet if needed
215            if ( is_rtl() ) {
216                wp_enqueue_style(
217                    $asset_handle . '-rtl',
218                    plugins_url( '_inc/build/' . $asset_name . '.rtl.css', JETPACK__PLUGIN_FILE ),
219                    array( $asset_handle ),
220                    $version
221                );
222            }
223        }
224
225        // Add any configuration data if needed
226        if ( ! empty( $options['config_data'] ) ) {
227            wp_add_inline_script(
228                $asset_handle,
229                "window.{$options['config_variable_name']} = " . wp_json_encode( $options['config_data'], JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ) . ';',
230                'before'
231            );
232        }
233    }
234}
235
236add_action(
237    'wp_dashboard_setup',
238    array( 'Jetpack_Newsletter_Dashboard_Widget', 'init' )
239);