← All changes
|
jetpack_vendor/automattic/jetpack-stats-admin/src/class-dashboard.php
+58
-10
16.2
→
16.3-beta
View file →
| @@ -6,9 +6,11 @@ | ||
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | 8 | namespace Automattic\Jetpack\Stats_Admin; |
| 9 | 9 | |
| 10 | +use Automattic\Jetpack\Admin_UI\Admin_Menu; | |
| 10 | 11 | use Automattic\Jetpack\Connection\Initial_State as Connection_Initial_State; |
| 12 | +use Automattic\Jetpack\Current_Plan as Jetpack_Plan; | |
| 11 | 13 | use Automattic\Jetpack\Stats\Options as Stats_Options; |
| 12 | 14 | |
| 13 | 15 | /** |
| 14 | 16 | * Responsible for adding a stats dashboard to wp-admin. |
| @@ -23,12 +25,20 @@ | ||
| 23 | 25 | */ |
| 24 | 26 | private static $initialized = false; |
| 25 | 27 | |
| 26 | 28 | /** |
| 29 | + * Transient that throttles the plan refresh below. | |
| 30 | + * | |
| 31 | + * @var string | |
| 32 | + */ | |
| 33 | + private const PLAN_REFRESH_TRANSIENT = 'jetpack_stats_admin_plan_refresh'; | |
| 34 | + | |
| 35 | + /** | |
| 27 | 36 | * Priority for the dashboard menu |
| 28 | 37 | * 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 | 38 | * |
| 39 | + * Admin_Menu registers what it has queued at priority 1000, so this has to stay below it. | |
| 40 | + * | |
| 31 | 41 | * @var int |
| 32 | 42 | */ |
| 33 | 43 | protected $menu_priority = 999; |
| 34 | 44 | |
| @@ -53,8 +63,11 @@ | ||
| 53 | 63 | |
| 54 | 64 | /** |
| 55 | 65 | * Add a "Stats" top-level admin menu. |
| 56 | 66 | * |
| 67 | + * Declares no `product` gate: that resolves false without the Jetpack plugin, which is | |
| 68 | + * exactly when the standalone Stats plugin registers this page. | |
| 69 | + * | |
| 57 | 70 | * @return void |
| 58 | 71 | */ |
| 59 | 72 | public function add_wp_admin_menu() { |
| 60 | 73 | /** |
| @@ -65,20 +78,27 @@ | ||
| 65 | 78 | if ( defined( 'IS_WPCOM' ) && IS_WPCOM && 120742 === get_current_blog_id() ) { |
| 66 | 79 | return; |
| 67 | 80 | } |
| 68 | 81 | |
| 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 | - ); | |
| 82 | + $page_title = __( 'Stats', 'jetpack-stats-admin' ); | |
| 83 | + $menu_title = _x( 'Stats', 'product name shown in menu', 'jetpack-stats-admin' ); | |
| 84 | + $capability = $this->get_capability(); | |
| 85 | + $callback = array( $this, 'render' ); | |
| 78 | 86 | |
| 87 | + // An older admin-ui, loaded first by another plugin, may predate add_top_level_menu(). | |
| 88 | + if ( method_exists( Admin_Menu::class, 'add_top_level_menu' ) ) { | |
| 89 | + // The key the legacy Stats screen in the Jetpack plugin also declares, so hosts name Stats once. | |
| 90 | + $page_suffix = Admin_Menu::add_top_level_menu( $page_title, $menu_title, $capability, 'stats', $callback, 'dashicons-chart-bar', 2, array( 'key' => 'jetpack-stats' ) ); | |
| 91 | + } else { | |
| 92 | + $page_suffix = add_menu_page( $page_title, $menu_title, $capability, 'stats', $callback, 'dashicons-chart-bar', 2 ); | |
| 93 | + } | |
| 94 | + | |
| 79 | 95 | if ( $page_suffix ) { |
| 80 | 96 | add_action( 'load-' . $page_suffix, array( $this, 'admin_init' ) ); |
| 97 | + // The dashboard renders full bleed, so core notices stacked above it look broken. | |
| 98 | + if ( method_exists( Admin_Menu::class, 'hide_core_admin_notices' ) ) { | |
| 99 | + add_action( 'load-' . $page_suffix, array( Admin_Menu::class, 'hide_core_admin_notices' ) ); | |
| 100 | + } | |
| 81 | 101 | } |
| 82 | 102 | } |
| 83 | 103 | |
| 84 | 104 | /** |
| @@ -157,9 +177,37 @@ | ||
| 157 | 177 | /** |
| 158 | 178 | * Initialize the admin resources. |
| 159 | 179 | */ |
| 160 | 180 | public function admin_init() { |
| 181 | + $this->maybe_refresh_plan(); | |
| 161 | 182 | add_action( 'admin_enqueue_scripts', array( $this, 'load_admin_scripts' ) ); |
| 183 | + } | |
| 184 | + | |
| 185 | + /** | |
| 186 | + * Fill an empty plan cache before the config data that reads it is printed. | |
| 187 | + * | |
| 188 | + * The app cannot refresh the plan it paywalls on, so a site that never stored one renders as | |
| 189 | + * free. Throttled and time-boxed, because WordPress.com can keep answering without a plan. | |
| 190 | + */ | |
| 191 | + private function maybe_refresh_plan() { | |
| 192 | + if ( ! Main::is_site_connected() ) { | |
| 193 | + return; | |
| 194 | + } | |
| 195 | + | |
| 196 | + // method_exists guard: an older plans package may win the autoloader on another plugin. | |
| 197 | + if ( method_exists( Jetpack_Plan::class, 'get_wpcom_site_specific_features' ) | |
| 198 | + && null !== Jetpack_Plan::get_wpcom_site_specific_features() ) { | |
| 199 | + return; | |
| 200 | + } | |
| 201 | + | |
| 202 | + $plan = Jetpack_Plan::get(); | |
| 203 | + if ( ! empty( $plan['features']['active'] ) || get_transient( self::PLAN_REFRESH_TRANSIENT ) ) { | |
| 204 | + return; | |
| 205 | + } | |
| 206 | + | |
| 207 | + set_transient( self::PLAN_REFRESH_TRANSIENT, 1, 15 * MINUTE_IN_SECONDS ); | |
| 208 | + | |
| 209 | + Jetpack_Plan::refresh_from_wpcom( array( 'timeout' => 5 ) ); | |
| 162 | 210 | } |
| 163 | 211 | |
| 164 | 212 | /** |
| 165 | 213 | * Load the admin scripts. |