PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 12.2.3
Jetpack – WP Security, Backup, Speed, & Growth v12.2.3
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 14.1.1 14.2.2 14.3.1 14.4.2 14.5.1 14.6.1 14.7.1 14.8.1 14.9.2 15.0.3 15.1.2 15.2.1 15.3.2 15.4.1 15.5.1 15.6.1 15.7.2 15.8.1 15.9.2 16.0.2 16.1.3 16.2-a.5 16.2-a.3 16.1.2 16.2-a.1 16.1.1 16.1 16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / _inc / lib / admin-pages / class.jetpack-admin-page.php
jetpack / _inc / lib / admin-pages Last commit date
class-jetpack-about-page.php 3 years ago class-jetpack-redux-state-helper.php 3 years ago class.jetpack-admin-page.php 3 years ago class.jetpack-landing-page.php 4 years ago class.jetpack-react-page.php 3 years ago class.jetpack-settings-page.php 3 years ago
class.jetpack-admin-page.php
460 lines
1 <?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2 /**
3 * Main class file for Jetpack Admin pages.
4 *
5 * @package automattic/jetpack
6 */
7
8 use Automattic\Jetpack\Identity_Crisis;
9 use Automattic\Jetpack\Redirect;
10 use Automattic\Jetpack\Status;
11
12 /**
13 * Shared logic between Jetpack admin pages.
14 */
15 abstract class Jetpack_Admin_Page {
16 /**
17 * Jetpack Object.
18 *
19 * @var Jetpack
20 */
21 public $jetpack;
22
23 /**
24 * Add page specific actions given the page hook.
25 *
26 * @param string $hook Hook of current page.
27 */
28 abstract public function add_page_actions( $hook );
29
30 /**
31 * Create a menu item for the page and returns the hook.
32 *
33 * @return string|false Return value from WordPress's `add_menu_page()` or `add_submenu_page()`.
34 */
35 abstract public function get_page_hook();
36
37 /**
38 * Enqueue and localize page specific scripts.
39 */
40 abstract public function page_admin_scripts();
41
42 /**
43 * Render page specific HTML
44 */
45 abstract public function page_render();
46
47 /**
48 * Should we block the page rendering because the site is in IDC?
49 *
50 * @var bool
51 */
52 public static $block_page_rendering_for_idc;
53
54 /**
55 * Function called after admin_styles to load any additional needed styles.
56 *
57 * @since 4.3.0
58 */
59 public function additional_styles() {}
60
61 /**
62 * The constructor.
63 */
64 public function __construct() {
65 add_action( 'jetpack_loaded', array( $this, 'on_jetpack_loaded' ) );
66 }
67
68 /**
69 * Runs on Jetpack being ready to load its packages.
70 *
71 * @param Jetpack $jetpack object.
72 */
73 public function on_jetpack_loaded( $jetpack ) {
74 $this->jetpack = $jetpack;
75
76 self::$block_page_rendering_for_idc = (
77 Jetpack::is_connection_ready() && Identity_Crisis::validate_sync_error_idc_option() && ! Jetpack_Options::get_option( 'safe_mode_confirmed' )
78 );
79 }
80
81 /**
82 * Add common page actions and attach page-specific actions.
83 */
84 public function add_actions() {
85 $is_offline_mode = ( new Status() )->is_offline_mode();
86
87 // If user is not an admin and site is in Offline Mode or not connected yet then don't do anything.
88 if ( ! current_user_can( 'manage_options' ) && ( $is_offline_mode || ! Jetpack::is_connection_ready() ) ) {
89 return;
90 }
91
92 // Is Jetpack not connected and not offline?
93 // True means that Jetpack is NOT connected and NOT in offline mode.
94 // If Jetpack is connected OR in offline mode, this will be false.
95 $connectable = ! Jetpack::is_connection_ready() && ! $is_offline_mode;
96
97 // Don't add in the modules page unless modules are available!
98 if ( $this->dont_show_if_not_active && $connectable ) {
99 return;
100 }
101
102 // Initialize menu item for the page in the admin.
103 $hook = $this->get_page_hook();
104
105 // Attach hooks common to all Jetpack admin pages based on the created hook.
106 add_action( "load-$hook", array( $this, 'admin_help' ) );
107 add_action( "load-$hook", array( $this, 'admin_page_load' ) );
108 add_action( "admin_print_styles-$hook", array( $this, 'admin_styles' ) );
109 add_action( "admin_print_scripts-$hook", array( $this, 'admin_scripts' ) );
110
111 if ( ! self::$block_page_rendering_for_idc ) {
112 add_action( "admin_print_styles-$hook", array( $this, 'additional_styles' ) );
113 }
114
115 // Check if the site plan changed and deactivate modules accordingly.
116 add_action( 'current_screen', array( $this, 'check_plan_deactivate_modules' ) );
117
118 // Attach page specific actions in addition to the above.
119 $this->add_page_actions( $hook );
120
121 // If the current user can connect Jetpack, Jetpack isn't connected, and is not in offline mode, let's prompt!
122 if ( current_user_can( 'jetpack_connect' ) && $connectable ) {
123 $this->add_connection_banner_actions();
124 }
125 }
126
127 /**
128 * Hooks to add when Jetpack is not active or in offline mode for an user capable of connecting.
129 */
130 private function add_connection_banner_actions() {
131 global $pagenow;
132 // If someone just activated Jetpack, let's show them a fullscreen connection banner.
133 if ( ( 'admin.php' === $pagenow && isset( $_GET['page'] ) && 'jetpack' === $_GET['page'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
134 add_action( 'admin_enqueue_scripts', array( 'Jetpack_Connection_Banner', 'enqueue_banner_scripts' ) );
135 add_action( 'admin_enqueue_scripts', array( 'Jetpack_Connection_Banner', 'enqueue_connect_button_scripts' ) );
136 delete_transient( 'activated_jetpack' );
137 }
138
139 // If Jetpack not yet connected, but user is viewing one of the pages with a Jetpack connection banner.
140 if ( ( 'index.php' === $pagenow || 'plugins.php' === $pagenow ) ) {
141 add_action( 'admin_enqueue_scripts', array( 'Jetpack_Connection_Banner', 'enqueue_connect_button_scripts' ) );
142 }
143 }
144
145 /**
146 * Render the page with a common top and bottom part, and page specific content.
147 */
148 public function render() {
149 // We're in an IDC: we need a decision made before we show the UI again.
150 if ( self::$block_page_rendering_for_idc ) {
151 return;
152 }
153
154 // Check if we are looking at the main dashboard.
155 if ( isset( $_GET['page'] ) && 'jetpack' === $_GET['page'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- View logic.
156 $this->page_render();
157 return;
158 }
159
160 $args = array();
161
162 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
163 if ( isset( $_GET['page'] ) && 'jetpack_modules' === $_GET['page'] ) {
164 $args['is-wide'] = true;
165 }
166
167 self::wrap_ui( array( $this, 'page_render' ), $args );
168 }
169
170 /**
171 * Load Help tab.
172 *
173 * @todo This may no longer be used.
174 */
175 public function admin_help() {
176 $this->jetpack->admin_help();
177 }
178
179 /**
180 * Call the existing admin page events.
181 */
182 public function admin_page_load() {
183 $this->jetpack->admin_page_load();
184 }
185
186 /**
187 * Add page specific scripts and jetpack stats for all menu pages.
188 */
189 public function admin_scripts() {
190 $this->page_admin_scripts(); // Delegate to inheriting class.
191 add_action( 'admin_footer', array( $this->jetpack, 'do_stats' ) );
192 }
193
194 /**
195 * Enqueue the Jetpack admin stylesheet.
196 */
197 public function admin_styles() {
198 $min = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
199
200 wp_enqueue_style( 'jetpack-admin', plugins_url( "css/jetpack-admin{$min}.css", JETPACK__PLUGIN_FILE ), array( 'genericons' ), JETPACK__VERSION . '-20121016' );
201 wp_style_add_data( 'jetpack-admin', 'rtl', 'replace' );
202 wp_style_add_data( 'jetpack-admin', 'suffix', $min );
203 }
204
205 /**
206 * Checks if REST API is enabled.
207 *
208 * @since 4.4.2
209 *
210 * @return bool
211 */
212 public function is_rest_api_enabled() {
213 return /** This filter is documented in wp-includes/rest-api/class-wp-rest-server.php */
214 apply_filters( 'rest_enabled', true ) &&
215 /** This filter is documented in wp-includes/rest-api/class-wp-rest-server.php */
216 apply_filters( 'rest_authentication_errors', true );
217 }
218
219 /**
220 * Checks the site plan and deactivates modules that were active but are no longer included in the plan.
221 *
222 * @since 4.4.0
223 *
224 * @param WP_Screen $page Current WP_Screen object.
225 *
226 * @return array
227 */
228 public function check_plan_deactivate_modules( $page ) {
229 if (
230 ( new Status() )->is_offline_mode()
231 || ! in_array(
232 $page->base,
233 array(
234 'toplevel_page_jetpack',
235 'admin_page_jetpack_modules',
236 'jetpack_page_vaultpress',
237 'jetpack_page_stats',
238 'jetpack_page_akismet-key-config',
239 ),
240 true
241 )
242 ) {
243 return false;
244 }
245
246 $current = Jetpack_Plan::get();
247
248 $to_deactivate = array();
249 if ( isset( $current['product_slug'] ) ) {
250 $active = Jetpack::get_active_modules();
251 switch ( $current['product_slug'] ) {
252 case 'jetpack_free':
253 case 'jetpack_personal':
254 case 'jetpack_personal_monthly':
255 $to_deactivate = array( 'google-analytics', 'wordads', 'search' );
256 break;
257 case 'jetpack_premium':
258 case 'jetpack_premium_monthly':
259 $to_deactivate = array( 'google-analytics', 'search' );
260 break;
261 }
262 $to_deactivate = array_intersect( $active, $to_deactivate );
263
264 $to_leave_enabled = array();
265 foreach ( $to_deactivate as $feature ) {
266 if ( Jetpack_Plan::supports( $feature ) ) {
267 $to_leave_enabled [] = $feature;
268 }
269 }
270 $to_deactivate = array_diff( $to_deactivate, $to_leave_enabled );
271
272 if ( ! empty( $to_deactivate ) ) {
273 Jetpack::update_active_modules( array_filter( array_diff( $active, $to_deactivate ) ) );
274 }
275 }
276 return array(
277 'current' => $current,
278 'deactivate' => $to_deactivate,
279 );
280 }
281
282 /**
283 * Enqueue inline wrapper styles for the main container.
284 */
285 public static function load_wrapper_styles() {
286 $rtl = is_rtl() ? '.rtl' : '';
287 wp_enqueue_style( 'dops-css', plugins_url( "_inc/build/admin{$rtl}.css", JETPACK__PLUGIN_FILE ), array(), JETPACK__VERSION );
288 wp_enqueue_style( 'components-css', plugins_url( "_inc/build/style.min{$rtl}.css", JETPACK__PLUGIN_FILE ), array( 'wp-components' ), JETPACK__VERSION );
289 }
290
291 /**
292 * Build header, content, and footer for admin page.
293 *
294 * @param string $callback Callback to produce the content of the page. The callback is responsible for any needed escaping.
295 * @param array $args Options for the wrapping. Also passed to the `jetpack_admin_pages_wrap_ui_after_callback` action.
296 * - is-wide: (bool) Set the "is-wide" class on the wrapper div, which increases the max width. Default false.
297 * - show-nav: (bool) Whether to show the navigation bar at the top of the page. Default true.
298 */
299 public static function wrap_ui( $callback, $args = array() ) {
300 $defaults = array(
301 'is-wide' => false,
302 'show-nav' => true,
303 );
304 $args = wp_parse_args( $args, $defaults );
305
306 // Is Jetpack not connected and not offline?
307 // True means that Jetpack is NOT connected and NOT in offline mode.
308 // If Jetpack is connected OR in offline mode, this will be false.
309 $connectable = ! Jetpack::is_connection_ready() && ! ( new Status() )->is_offline_mode();
310
311 $jetpack_admin_url = admin_url( 'admin.php?page=jetpack' );
312 $jetpack_about_url = ! $connectable
313 ? admin_url( 'admin.php?page=jetpack_about' )
314 : Redirect::get_url( 'jetpack' );
315
316 $jetpack_privacy_url = ! $connectable
317 ? $jetpack_admin_url . '#/privacy'
318 : Redirect::get_url( 'a8c-privacy' );
319
320 $external_link_icon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" class="jp-footer__menu-item__icon" aria-hidden="true" focusable="false"><path d="M18.2 17c0 .7-.6 1.2-1.2 1.2H7c-.7 0-1.2-.6-1.2-1.2V7c0-.7.6-1.2 1.2-1.2h3.2V4.2H7C5.5 4.2 4.2 5.5 4.2 7v10c0 1.5 1.2 2.8 2.8 2.8h10c1.5 0 2.8-1.2 2.8-2.8v-3.6h-1.5V17zM14.9 3v1.5h3.7l-6.4 6.4 1.1 1.1 6.4-6.4v3.7h1.5V3h-6.3z"></path></svg>';
321
322 ?>
323 <div id="jp-plugin-container" class="
324 <?php
325 if ( $args['is-wide'] ) {
326 echo 'is-wide'; }
327 ?>
328 ">
329
330 <div class="jp-masthead jp-masthead-middle">
331 <div class="jp-masthead__inside-container">
332 <div class="jp-masthead__logo-container">
333 <a class="jp-masthead__logo-link" href="<?php echo esc_url( $jetpack_admin_url ); ?>">
334 <svg class="jetpack-logo__masthead" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" height="40" viewBox="0 0 118 32"><path fill="#069e08" d="M16,0C7.2,0,0,7.2,0,16s7.2,16,16,16s16-7.2,16-16S24.8,0,16,0z M15,19H7l8-16V19z M17,29V13h8L17,29z"></path><path d="M41.3,26.6c-0.5-0.7-0.9-1.4-1.3-2.1c2.3-1.4,3-2.5,3-4.6V8h-3V6h6v13.4C46,22.8,45,24.8,41.3,26.6z"></path><path d="M65,18.4c0,1.1,0.8,1.3,1.4,1.3c0.5,0,2-0.2,2.6-0.4v2.1c-0.9,0.3-2.5,0.5-3.7,0.5c-1.5,0-3.2-0.5-3.2-3.1V12H60v-2h2.1V7.1 H65V10h4v2h-4V18.4z"></path><path d="M71,10h3v1.3c1.1-0.8,1.9-1.3,3.3-1.3c2.5,0,4.5,1.8,4.5,5.6s-2.2,6.3-5.8,6.3c-0.9,0-1.3-0.1-2-0.3V28h-3V10z M76.5,12.3 c-0.8,0-1.6,0.4-2.5,1.2v5.9c0.6,0.1,0.9,0.2,1.8,0.2c2,0,3.2-1.3,3.2-3.9C79,13.4,78.1,12.3,76.5,12.3z"></path><path d="M93,22h-3v-1.5c-0.9,0.7-1.9,1.5-3.5,1.5c-1.5,0-3.1-1.1-3.1-3.2c0-2.9,2.5-3.4,4.2-3.7l2.4-0.3v-0.3c0-1.5-0.5-2.3-2-2.3 c-0.7,0-2.3,0.5-3.7,1.1L84,11c1.2-0.4,3-1,4.4-1c2.7,0,4.6,1.4,4.6,4.7L93,22z M90,16.4l-2.2,0.4c-0.7,0.1-1.4,0.5-1.4,1.6 c0,0.9,0.5,1.4,1.3,1.4s1.5-0.5,2.3-1V16.4z"></path><path d="M104.5,21.3c-1.1,0.4-2.2,0.6-3.5,0.6c-4.2,0-5.9-2.4-5.9-5.9c0-3.7,2.3-6,6.1-6c1.4,0,2.3,0.2,3.2,0.5V13 c-0.8-0.3-2-0.6-3.2-0.6c-1.7,0-3.2,0.9-3.2,3.6c0,2.9,1.5,3.8,3.3,3.8c0.9,0,1.9-0.2,3.2-0.7V21.3z"></path><path d="M110,15.2c0.2-0.3,0.2-0.8,3.8-5.2h3.7l-4.6,5.7l5,6.3h-3.7l-4.2-5.8V22h-3V6h3V15.2z"></path><path d="M58.5,21.3c-1.5,0.5-2.7,0.6-4.2,0.6c-3.6,0-5.8-1.8-5.8-6c0-3.1,1.9-5.9,5.5-5.9s4.9,2.5,4.9,4.9c0,0.8,0,1.5-0.1,2h-7.3 c0.1,2.5,1.5,2.8,3.6,2.8c1.1,0,2.2-0.3,3.4-0.7C58.5,19,58.5,21.3,58.5,21.3z M56,15c0-1.4-0.5-2.9-2-2.9c-1.4,0-2.3,1.3-2.4,2.9 C51.6,15,56,15,56,15z"></path></svg>
335 </a>
336 </div>
337 <?php
338 if ( $args['show-nav'] ) :
339 ?>
340 <div class="jp-masthead__nav">
341 <?php
342 if ( is_network_admin() ) {
343 $current_screen = get_current_screen();
344
345 $highlight_current_sites = ( 'toplevel_page_jetpack-network' === $current_screen->id ? 'is-primary' : '' );
346 $highlight_current_settings = ( 'jetpack_page_jetpack-settings-network' === $current_screen->id ? 'is-primary' : '' );
347 ?>
348 <span class="dops-button-group">
349 <?php
350 if ( current_user_can( 'jetpack_network_sites_page' ) ) {
351 ?>
352 <a href="<?php echo esc_url( network_admin_url( 'admin.php?page=jetpack' ) ); ?>" type="button" class="<?php echo esc_attr( $highlight_current_sites ); ?> dops-button is-compact" title="<?php esc_html_e( "Manage your network's Jetpack Sites.", 'jetpack' ); ?>"><?php echo esc_html_x( 'Sites', 'Navigation item', 'jetpack' ); ?></a>
353 <?php
354 } if ( current_user_can( 'jetpack_network_settings_page' ) ) {
355 ?>
356 <a href="<?php echo esc_url( network_admin_url( 'admin.php?page=jetpack-settings' ) ); ?>" type="button" class="<?php echo esc_attr( $highlight_current_settings ); ?> dops-button is-compact" title="<?php esc_html_e( "Manage your network's Jetpack Sites.", 'jetpack' ); ?>"><?php echo esc_html_x( 'Network Settings', 'Navigation item', 'jetpack' ); ?></a>
357 <?php
358 }
359 ?>
360 </span>
361 <?php } else { ?>
362 <span class="dops-button-group">
363 <a href="<?php echo esc_url( $jetpack_admin_url ); ?>" type="button" class="dops-button is-compact"><?php esc_html_e( 'Dashboard', 'jetpack' ); ?></a>
364 <?php
365 if ( current_user_can( 'jetpack_manage_modules' ) ) {
366 ?>
367 <a href="<?php echo esc_url( $jetpack_admin_url . '#/settings' ); ?>" type="button" class="dops-button is-compact"><?php esc_html_e( 'Settings', 'jetpack' ); ?></a>
368 <?php
369 }
370 ?>
371 </span>
372 <?php } ?>
373 </div>
374 <?php endif; ?>
375 </div>
376 </div>
377 <div class="wrap"><div id="jp-admin-notices" aria-live="polite"></div></div>
378 <!-- START OF CALLBACK -->
379 <?php
380 ob_start();
381 call_user_func( $callback );
382 $callback_ui = ob_get_contents();
383 ob_end_clean();
384 echo $callback_ui;// phpcs:ignore WordPress.Security.EscapeOutput -- Callback is responsible for any needed escaping.
385 ?>
386 <!-- END OF CALLBACK -->
387
388 <div id="jp-stats-report-bottom">
389 <div class="wrap">
390 <?php
391 /**
392 * Fires at the bottom of the Jetpack admin page template, after the dynamic content section.
393 *
394 * @since 10.0.0
395 *
396 * @param string $callback The callback sent to the Jetpack_Admin_Page::wrap_ui method.
397 * @param array $args The arguments sent to the Jetpack_Admin_Page::wrap_ui method.
398 */
399 do_action( 'jetpack_admin_pages_wrap_ui_after_callback', $callback, $args );
400 ?>
401 </div>
402 </div>
403
404 <div class="jp-footer jp-footer--static">
405 <div class="jp-footer__container">
406 <div class="jp-footer__logo">
407 <svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 32 32" class="jetpack-logo jp-footer__jetpack-symbol" aria-labelledby="jetpack-logo-title" height="16" aria-label="<?php esc_html_e( 'Jetpack logo', 'jetpack' ); ?>">
408 <desc id="jetpack-logo-title">
409 <?php esc_html_e( 'Jetpack Logo', 'jetpack' ); ?>
410 </desc>
411 <path fill="#000" d="M16,0C7.2,0,0,7.2,0,16s7.2,16,16,16s16-7.2,16-16S24.8,0,16,0z M15,19H7l8-16V19z M17,29V13h8L17,29z"></path>
412 </svg>
413 <span class="jp-footer__module-name">
414 <a href="<?php echo esc_url( Redirect::get_url( 'jetpack' ) ); ?>" target="_blank" rel="noopener noreferrer" aria-label="Jetpack 12.2-a.0">
415 <?php esc_html_e( 'Jetpack', 'jetpack' ); ?>
416 </a>
417 </span>
418 </div>
419 <div class="jp-footer__menu">
420 <a href="<?php echo esc_url( $jetpack_about_url ); ?>" title="<?php esc_attr__( 'About Jetpack', 'jetpack' ); ?>" class="jp-footer__menu-item">
421 <?php echo esc_html__( 'About', 'jetpack' ); ?>
422 </a>
423 <a href="<?php echo esc_url( $jetpack_privacy_url ); ?>" rel="noopener noreferrer" title="<?php esc_html_e( "Automattic's Privacy Policy", 'jetpack' ); ?>" class="jp-footer__menu-item <?php echo ! $connectable ? 'is-external' : ''; ?> ?>" target="<?php echo ! $connectable ? '_blank' : '_self'; ?>">
424 <?php echo esc_html_x( 'Privacy', 'Navigation item', 'jetpack' ); ?>
425 <?php echo ! $connectable ? $external_link_icon : ''; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
426 </a>
427 <a href="<?php echo esc_url( Redirect::get_url( 'wpcom-tos' ) ); ?>" target="_blank" rel="noopener noreferrer" title="<?php esc_html__( 'WordPress.com Terms of Service', 'jetpack' ); ?>" class="jp-footer__menu-item is-external">
428 <?php echo esc_html_x( 'Terms', 'Navigation item', 'jetpack' ); ?>
429 <?php echo $external_link_icon; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
430 </a>
431 <a href="<?php echo esc_url( Redirect::get_url( 'jetpack' ) ); ?>" target="_blank" rel="noopener noreferrer" aria-label="Jetpack 12.2-a.0" class="jp-footer__menu-item is-external">
432 Version <?php echo esc_html( JETPACK__VERSION ); ?>
433 <?php echo $external_link_icon; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
434 </a>
435 <?php if ( is_multisite() && current_user_can( 'jetpack_network_sites_page' ) ) { ?>
436 <a href="<?php echo esc_url( network_admin_url( 'admin.php?page=jetpack' ) ); ?>" title="<?php esc_html_e( "Manage your network's Jetpack Sites.", 'jetpack' ); ?>" class="jp-footer__menu-item"><?php echo esc_html_x( 'Network Sites', 'Navigation item', 'jetpack' ); ?></a>
437 <?php } ?>
438 <?php if ( is_multisite() && current_user_can( 'jetpack_network_settings_page' ) ) { ?>
439 <a href="<?php echo esc_url( network_admin_url( 'admin.php?page=jetpack-settings' ) ); ?>" title="<?php esc_html_e( "Manage your network's Jetpack Sites.", 'jetpack' ); ?>" class="jp-footer__menu-item"><?php echo esc_html_x( 'Network Settings', 'Navigation item', 'jetpack' ); ?></a>
440 <?php } ?>
441 <?php if ( current_user_can( 'manage_options' ) ) { ?>
442 <a href="<?php echo esc_url( admin_url( 'admin.php?page=jetpack_modules' ) ); ?>" title="<?php esc_html_e( 'Access the full list of Jetpack modules available on your site.', 'jetpack' ); ?>" class="jp-footer__menu-item"><?php echo esc_html_x( 'Modules', 'Navigation item', 'jetpack' ); ?></a>
443 <a href="<?php echo esc_url( admin_url( 'admin.php?page=jetpack-debugger' ) ); ?>" title="<?php esc_html_e( "Test your site's compatibility with Jetpack.", 'jetpack' ); ?>" class="jp-footer__menu-item"><?php echo esc_html_x( 'Debug', 'Navigation item', 'jetpack' ); ?></a>
444 <?php } ?>
445 </div>
446 <a class="jp-footer__a8c-logo" href="<?php echo esc_url( $jetpack_about_url ); ?>" aria-label="<?php echo esc_attr__( 'An Automattic Airline', 'jetpack' ); ?>">
447 <svg role="img" x="0" y="0" viewBox="0 0 935 38.2" enable-background="new 0 0 935 38.2" aria-labelledby="jp-automattic-byline-logo-title" height="7" class="jp-automattic-byline-logo">
448 <desc id="jp-automattic-byline-logo-title">
449 <?php echo esc_attr__( 'An Automattic Airline', 'jetpack' ); ?>
450 </desc>
451 <path d="M317.1 38.2c-12.6 0-20.7-9.1-20.7-18.5v-1.2c0-9.6 8.2-18.5 20.7-18.5 12.6 0 20.8 8.9 20.8 18.5v1.2C337.9 29.1 329.7 38.2 317.1 38.2zM331.2 18.6c0-6.9-5-13-14.1-13s-14 6.1-14 13v0.9c0 6.9 5 13.1 14 13.1s14.1-6.2 14.1-13.1V18.6zM175 36.8l-4.7-8.8h-20.9l-4.5 8.8h-7L157 1.3h5.5L182 36.8H175zM159.7 8.2L152 23.1h15.7L159.7 8.2zM212.4 38.2c-12.7 0-18.7-6.9-18.7-16.2V1.3h6.6v20.9c0 6.6 4.3 10.5 12.5 10.5 8.4 0 11.9-3.9 11.9-10.5V1.3h6.7V22C231.4 30.8 225.8 38.2 212.4 38.2zM268.6 6.8v30h-6.7v-30h-15.5V1.3h37.7v5.5H268.6zM397.3 36.8V8.7l-1.8 3.1 -14.9 25h-3.3l-14.7-25 -1.8-3.1v28.1h-6.5V1.3h9.2l14 24.4 1.7 3 1.7-3 13.9-24.4h9.1v35.5H397.3zM454.4 36.8l-4.7-8.8h-20.9l-4.5 8.8h-7l19.2-35.5h5.5l19.5 35.5H454.4zM439.1 8.2l-7.7 14.9h15.7L439.1 8.2zM488.4 6.8v30h-6.7v-30h-15.5V1.3h37.7v5.5H488.4zM537.3 6.8v30h-6.7v-30h-15.5V1.3h37.7v5.5H537.3zM569.3 36.8V4.6c2.7 0 3.7-1.4 3.7-3.4h2.8v35.5L569.3 36.8 569.3 36.8zM628 11.3c-3.2-2.9-7.9-5.7-14.2-5.7 -9.5 0-14.8 6.5-14.8 13.3v0.7c0 6.7 5.4 13 15.3 13 5.9 0 10.8-2.8 13.9-5.7l4 4.2c-3.9 3.8-10.5 7.1-18.3 7.1 -13.4 0-21.6-8.7-21.6-18.3v-1.2c0-9.6 8.9-18.7 21.9-18.7 7.5 0 14.3 3.1 18 7.1L628 11.3zM321.5 12.4c1.2 0.8 1.5 2.4 0.8 3.6l-6.1 9.4c-0.8 1.2-2.4 1.6-3.6 0.8l0 0c-1.2-0.8-1.5-2.4-0.8-3.6l6.1-9.4C318.7 11.9 320.3 11.6 321.5 12.4L321.5 12.4z"></path><path d="M37.5 36.7l-4.7-8.9H11.7l-4.6 8.9H0L19.4 0.8H25l19.7 35.9H37.5zM22 7.8l-7.8 15.1h15.9L22 7.8zM82.8 36.7l-23.3-24 -2.3-2.5v26.6h-6.7v-36H57l22.6 24 2.3 2.6V0.8h6.7v35.9H82.8z"></path><path d="M719.9 37l-4.8-8.9H694l-4.6 8.9h-7.1l19.5-36h5.6l19.8 36H719.9zM704.4 8l-7.8 15.1h15.9L704.4 8zM733 37V1h6.8v36H733zM781 37c-1.8 0-2.6-2.5-2.9-5.8l-0.2-3.7c-0.2-3.6-1.7-5.1-8.4-5.1h-12.8V37H750V1h19.6c10.8 0 15.7 4.3 15.7 9.9 0 3.9-2 7.7-9 9 7 0.5 8.5 3.7 8.6 7.9l0.1 3c0.1 2.5 0.5 4.3 2.2 6.1V37H781zM778.5 11.8c0-2.6-2.1-5.1-7.9-5.1h-13.8v10.8h14.4c5 0 7.3-2.4 7.3-5.2V11.8zM794.8 37V1h6.8v30.4h28.2V37H794.8zM836.7 37V1h6.8v36H836.7zM886.2 37l-23.4-24.1 -2.3-2.5V37h-6.8V1h6.5l22.7 24.1 2.3 2.6V1h6.8v36H886.2zM902.3 37V1H935v5.6h-26v9.2h20v5.5h-20v10.1h26V37H902.3z"></path>
452 </svg>
453 </a>
454 </div>
455 </div>
456 </div>
457 <?php
458 }
459 }
460