PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-a.1
Jetpack – WP Security, Backup, Speed, & Growth v16.3-a.1
16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 All 504 releases
jetpack / jetpack_vendor / automattic / jetpack-stats-admin / src / class-dashboard.php

class-dashboard.php in Jetpack – WP Security, Backup, Speed, & Growth 16.3-a.1, at jetpack_vendor/automattic/jetpack-stats-admin/src/class-dashboard.php

187 lines 6.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * A class that adds a stats dashboard to wp-admin.
4 *
5 * @package automattic/jetpack-stats-admin
6 */
7
8 namespace Automattic\Jetpack\Stats_Admin;
9
10 use Automattic\Jetpack\Connection\Initial_State as Connection_Initial_State;
11 use Automattic\Jetpack\Stats\Options as Stats_Options;
12
13 /**
14 * Responsible for adding a stats dashboard to wp-admin.
15 *
16 * @package jetpack-stats-admin
17 */
18 class Dashboard {
19 /**
20 * Whether the class has been initialized
21 *
22 * @var boolean
23 */
24 private static $initialized = false;
25
26 /**
27 * Priority for the dashboard menu
28 * For Jetpack sites: Jetpack uses 998 and 'Admin_Menu' uses 1000, so we need to use 999.
29 * For simple site: the value is overriden in a child class with value 100000 to wait for all menus to be registered.
30 *
31 * @var int
32 */
33 protected $menu_priority = 999;
34
35 /**
36 * Init Stats dashboard.
37 */
38 public static function init() {
39 if ( ! self::$initialized ) {
40 self::$initialized = true;
41 ( new self() )->init_hooks();
42 }
43 }
44
45 /**
46 * Initialize the hooks.
47 */
48 public function init_hooks() {
49 self::$initialized = true;
50 // Jetpack uses 998 and 'Admin_Menu' uses 1000.
51 add_action( 'admin_menu', array( $this, 'add_wp_admin_menu' ), $this->menu_priority );
52 }
53
54 /**
55 * Add a "Stats" top-level admin menu.
56 *
57 * @return void
58 */
59 public function add_wp_admin_menu() {
60 /**
61 * Disable this menu for dashboard.wordpress.com because older versions of Jetpack need to fetch the old Stats UI.
62 *
63 * If this menu is registered, it will conflict with the back-end and break non-odyssey Stats.
64 */
65 if ( defined( 'IS_WPCOM' ) && IS_WPCOM && 120742 === get_current_blog_id() ) {
66 return;
67 }
68
69 $page_suffix = add_menu_page(
70 __( 'Stats', 'jetpack-stats-admin' ),
71 _x( 'Stats', 'product name shown in menu', 'jetpack-stats-admin' ),
72 $this->get_capability(),
73 'stats',
74 array( $this, 'render' ),
75 'dashicons-chart-bar',
76 2
77 );
78
79 if ( $page_suffix ) {
80 add_action( 'load-' . $page_suffix, array( $this, 'admin_init' ) );
81 }
82 }
83
84 /**
85 * Capability a user needs to reach the dashboard.
86 *
87 * Until the site is connected the page exists to pick a plan and connect, which only a user
88 * who can manage the connection can act on. Once connected it is a reporting page, open to
89 * everyone allowed to view stats.
90 *
91 * Pre-connection that is `jetpack_connect`: it maps to `manage_options` on a normal site,
92 * but is `do_not_allow` in offline mode and honours the same multisite/filter rules as the
93 * register endpoint, so the menu is not offered where the connection cannot be completed.
94 *
95 * @return string
96 */
97 protected function get_capability() {
98 return Main::is_site_connected() ? 'view_stats' : 'jetpack_connect';
99 }
100
101 /**
102 * Override render funtion
103 */
104 public function render() {
105 // Record the number of views of the stats dashboard on the initial several loads for the
106 // purpose of showing feedback notice. Views before the site is connected show the plan
107 // choice rather than the dashboard, and there is nothing to give feedback on yet.
108 $views = intval( Stats_Options::get_option( 'views' ) ) + 1;
109 if ( $views <= Notices::VIEWS_TO_SHOW_FEEDBACK && Main::is_site_connected() ) {
110 Stats_Options::set_option( 'views', $views );
111 }
112
113 ?>
114 <div id="wpcom" class="jp-stats-dashboard" style="min-height: calc(100vh - 100px);">
115 <div class="hide-if-js"><?php esc_html_e( 'Your Jetpack Stats dashboard requires JavaScript to function properly.', 'jetpack-stats-admin' ); ?></div>
116 <div class="hide-if-no-js" style="height: 100%">
117 <img
118 class="jp-stats-dashboard-loading-spinner"
119 width="32"
120 height="32"
121 style="position: absolute; left: 50%; top: 50%;"
122 alt=<?php echo esc_attr( __( 'Loading', 'jetpack-stats-admin' ) ); ?>
123 src="//en.wordpress.com/i/loading/loading-64.gif"
124 />
125 </div>
126 </div>
127 <?php
128 }
129
130 /**
131 * The dashboard bootstrap: load the icon sprite, and keep in-app links inside the dashboard.
132 *
133 * @return string
134 */
135 private function get_bootstrap_script() {
136 return <<<'JS'
137 jQuery(document).ready(function($) {
138 // Load SVG sprite.
139 $.get("https://widgets.wp.com/odyssey-stats/common/gridicons-506499ddac13811fee8e.svg", function(data) {
140 var div = document.createElement("div");
141 div.innerHTML = new XMLSerializer().serializeToString(data.documentElement);
142 div.style = 'display: none';
143 document.body.insertBefore(div, document.body.childNodes[0]);
144 });
145 // we intercept on all anchor tags and change it to hashbang style.
146 $("#wpcom").on('click', 'a', function (e) {
147 const link = e && e.currentTarget && e.currentTarget.attributes && e.currentTarget.attributes.href && e.currentTarget.attributes.href.value;
148 if( link && link.startsWith( '/stats' ) ) {
149 location.hash = `#!${link}`;
150 return false;
151 }
152 });
153 });
154 JS;
155 }
156
157 /**
158 * Initialize the admin resources.
159 */
160 public function admin_init() {
161 add_action( 'admin_enqueue_scripts', array( $this, 'load_admin_scripts' ) );
162 }
163
164 /**
165 * Load the admin scripts.
166 */
167 public function load_admin_scripts() {
168 ( new Odyssey_Assets() )->load_admin_scripts( 'jp-stats-dashboard', 'build.min', array( 'config_variable_name' => 'jetpackStatsOdysseyAppConfigData' ) );
169
170 // The bootstrap runs on jQuery, which the Odyssey bundle does not depend on. It gets its own
171 // handle rather than jQuery being added to that bundle, which the dashboard widget shares
172 // and which has no use for it.
173 wp_register_script( 'jp-stats-dashboard-bootstrap', false, array( 'jquery' ), Main::VERSION, true );
174 wp_enqueue_script( 'jp-stats-dashboard-bootstrap' );
175 wp_add_inline_script( 'jp-stats-dashboard-bootstrap', $this->get_bootstrap_script() );
176
177 // The app is served from our CDN and so cannot bundle the connection package. Print the
178 // state Search and Protect print on their own pages, so it can read the connection status
179 // and register the site through the connection REST API itself. Connected sites fetch
180 // `jetpack/v4/connection` over REST instead, and must not receive registrationNonce and
181 // the connected-plugin list on a page that `view_stats` users can open.
182 if ( ! Main::is_site_connected() ) {
183 Connection_Initial_State::render_script( 'jp-stats-dashboard' );
184 }
185 }
186 }
187