Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
70.00% covered (warning)
70.00%
35 / 50
50.00% covered (danger)
50.00%
3 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
Dashboard
70.00% covered (warning)
70.00%
35 / 50
50.00% covered (danger)
50.00%
3 / 6
15.89
0.00% covered (danger)
0.00%
0 / 1
 init
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 init_hooks
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 add_wp_admin_menu
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
30
 render
100.00% covered (success)
100.00%
30 / 30
100.00% covered (success)
100.00%
1 / 1
2
 admin_init
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 load_admin_scripts
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * A class that adds a stats dashboard to wp-admin.
4 *
5 * @package automattic/jetpack-stats-admin
6 */
7
8namespace Automattic\Jetpack\Stats_Admin;
9
10use Automattic\Jetpack\Stats\Options as Stats_Options;
11
12/**
13 * Responsible for adding a stats dashboard to wp-admin.
14 *
15 * @package jetpack-stats-admin
16 */
17class Dashboard {
18    /**
19     * Whether the class has been initialized
20     *
21     * @var boolean
22     */
23    private static $initialized = false;
24
25    /**
26     * Priority for the dashboard menu
27     * For Jetpack sites: Jetpack uses 998 and 'Admin_Menu' uses 1000, so we need to use 999.
28     * For simple site: the value is overriden in a child class with value 100000 to wait for all menus to be registered.
29     *
30     * @var int
31     */
32    protected $menu_priority = 999;
33
34    /**
35     * Init Stats dashboard.
36     */
37    public static function init() {
38        if ( ! self::$initialized ) {
39            self::$initialized = true;
40            ( new self() )->init_hooks();
41        }
42    }
43
44    /**
45     * Initialize the hooks.
46     */
47    public function init_hooks() {
48        self::$initialized = true;
49        // Jetpack uses 998 and 'Admin_Menu' uses 1000.
50        add_action( 'admin_menu', array( $this, 'add_wp_admin_menu' ), $this->menu_priority );
51    }
52
53    /**
54     * Add a "Stats" top-level admin menu.
55     *
56     * @return void
57     */
58    public function add_wp_admin_menu() {
59        /**
60         * Disable this menu for dashboard.wordpress.com because older versions of Jetpack need to fetch the old Stats UI.
61         *
62         * If this menu is registered, it will conflict with the back-end and break non-odyssey Stats.
63         */
64        if ( defined( 'IS_WPCOM' ) && IS_WPCOM && 120742 === get_current_blog_id() ) {
65            return;
66        }
67
68        $page_suffix = add_menu_page(
69            __( 'Stats', 'jetpack-stats-admin' ),
70            _x( 'Stats', 'product name shown in menu', 'jetpack-stats-admin' ),
71            'view_stats',
72            'stats',
73            array( $this, 'render' ),
74            'dashicons-chart-bar',
75            2
76        );
77
78        if ( $page_suffix ) {
79            add_action( 'load-' . $page_suffix, array( $this, 'admin_init' ) );
80        }
81    }
82
83    /**
84     * Override render funtion
85     */
86    public function render() {
87        // Record the number of views of the stats dashboard on the initial several loads for the purpose of showing feedback notice.
88        $views = intval( Stats_Options::get_option( 'views' ) ) + 1;
89        if ( $views <= Notices::VIEWS_TO_SHOW_FEEDBACK ) {
90            Stats_Options::set_option( 'views', $views );
91        }
92
93        ?>
94        <div id="wpcom" class="jp-stats-dashboard" style="min-height: calc(100vh - 100px);">
95            <div class="hide-if-js"><?php esc_html_e( 'Your Jetpack Stats dashboard requires JavaScript to function properly.', 'jetpack-stats-admin' ); ?></div>
96            <div class="hide-if-no-js" style="height: 100%">
97                <img
98                    class="jp-stats-dashboard-loading-spinner"
99                    width="32"
100                    height="32"
101                    style="position: absolute; left: 50%; top: 50%;"
102                    alt=<?php echo esc_attr( __( 'Loading', 'jetpack-stats-admin' ) ); ?>
103                    src="//en.wordpress.com/i/loading/loading-64.gif"
104                />
105            </div>
106        </div>
107        <script>
108            jQuery(document).ready(function($) {
109                // Load SVG sprite.
110                $.get("https://widgets.wp.com/odyssey-stats/common/gridicons-506499ddac13811fee8e.svg", function(data) {
111                    var div = document.createElement("div");
112                    div.innerHTML = new XMLSerializer().serializeToString(data.documentElement);
113                    div.style = 'display: none';
114                    document.body.insertBefore(div, document.body.childNodes[0]);
115                });
116                // we intercept on all anchor tags and change it to hashbang style.
117                $("#wpcom").on('click', 'a', function (e) {
118                    const link = e && e.currentTarget && e.currentTarget.attributes && e.currentTarget.attributes.href && e.currentTarget.attributes.href.value;
119                    if( link && link.startsWith( '/stats' ) ) {
120                        location.hash = `#!${link}`;
121                        return false;
122                    }
123                });
124            });
125        </script>
126        <?php
127    }
128
129    /**
130     * Initialize the admin resources.
131     */
132    public function admin_init() {
133        add_action( 'admin_enqueue_scripts', array( $this, 'load_admin_scripts' ) );
134    }
135
136    /**
137     * Load the admin scripts.
138     */
139    public function load_admin_scripts() {
140        ( new Odyssey_Assets() )->load_admin_scripts( 'jp-stats-dashboard', 'build.min', array( 'config_variable_name' => 'jetpackStatsOdysseyAppConfigData' ) );
141    }
142}