193 lines
4.5 KiB
PHP
193 lines
4.5 KiB
PHP
|
|
<?php
|
||
|
|
/**
|
||
|
|
* A class that adds a scan and backup link to the admin sidebar.
|
||
|
|
*
|
||
|
|
* @package automattic/jetpack
|
||
|
|
*/
|
||
|
|
|
||
|
|
namespace Automattic\Jetpack\Scan;
|
||
|
|
|
||
|
|
use Automattic\Jetpack\Redirect;
|
||
|
|
use Jetpack_Core_Json_Api_Endpoints;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Class Main
|
||
|
|
*
|
||
|
|
* Responsible for showing the link if available.
|
||
|
|
*
|
||
|
|
* @package Automattic\Jetpack\Scan
|
||
|
|
*/
|
||
|
|
class Admin_Sidebar_Link {
|
||
|
|
|
||
|
|
const SCHEDULE_ACTION_HOOK = 'jetpack_scan_refresh_states_event';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The singleton instance of this class.
|
||
|
|
*
|
||
|
|
* @var Admin_Sidebar_Link
|
||
|
|
*/
|
||
|
|
protected static $instance;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Used to check if we need to schedule the refresh or we need to do it.
|
||
|
|
*
|
||
|
|
* @var boolean | null
|
||
|
|
*/
|
||
|
|
private $schedule_refresh_checked;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the singleton instance of the class.
|
||
|
|
*
|
||
|
|
* @return Admin_Sidebar_Link
|
||
|
|
*/
|
||
|
|
public static function instance() {
|
||
|
|
if ( ! isset( self::$instance ) ) {
|
||
|
|
self::$instance = new Admin_Sidebar_Link();
|
||
|
|
self::$instance->init_hooks();
|
||
|
|
}
|
||
|
|
|
||
|
|
return self::$instance;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Adds action hooks.
|
||
|
|
*/
|
||
|
|
public function init_hooks() {
|
||
|
|
add_action( 'jetpack_admin_menu', array( $this, 'maybe_add_admin_link' ), 99 );
|
||
|
|
add_action( self::SCHEDULE_ACTION_HOOK, array( $this, 'refresh_state_cache' ) );
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Adds a link to the Scan and Backup page.
|
||
|
|
*/
|
||
|
|
public function maybe_add_admin_link() {
|
||
|
|
if ( ! $this->should_show_link() ) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
$new_link = $this->get_new_link();
|
||
|
|
|
||
|
|
// Splice the nav menu item into the Jetpack nav.
|
||
|
|
global $submenu;
|
||
|
|
array_splice( $submenu['jetpack'], $this->get_link_offset(), 0, array( $new_link ) );
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Retuns the new link.
|
||
|
|
*
|
||
|
|
* @return array Link array to be added to the sidebar.
|
||
|
|
*/
|
||
|
|
private function get_new_link() {
|
||
|
|
$has_scan = $this->has_scan();
|
||
|
|
$has_backup = $this->has_backup();
|
||
|
|
|
||
|
|
$url = Redirect::get_url( 'calypso-backups' );
|
||
|
|
if ( $has_scan && ! $has_backup ) {
|
||
|
|
$menu_label = __( 'Scan', 'jetpack' );
|
||
|
|
$url = Redirect::get_url( 'calypso-scanner' );
|
||
|
|
} elseif ( ! $has_scan && $has_backup ) {
|
||
|
|
$menu_label = __( 'Backup', 'jetpack' );
|
||
|
|
} else {
|
||
|
|
// Will be both, as the code won't get this far if neither is true.
|
||
|
|
$menu_label = __( 'Backup & Scan', 'jetpack' );
|
||
|
|
}
|
||
|
|
|
||
|
|
return array(
|
||
|
|
esc_html( $menu_label ) . ' <span class="dashicons dashicons-external"></span>',
|
||
|
|
'manage_options', // Check permissions here.
|
||
|
|
esc_url( $url ),
|
||
|
|
);
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* We create a menu offset by counting all the pages that have a jetpack_admin_page set as the link.
|
||
|
|
*
|
||
|
|
* This makes it so that the highlight of the pages works as expected. When you click on the Setting or Dashboard.
|
||
|
|
*
|
||
|
|
* @return int Menu offset.
|
||
|
|
*/
|
||
|
|
private function get_link_offset() {
|
||
|
|
global $submenu;
|
||
|
|
$offset = 0;
|
||
|
|
foreach ( $submenu['jetpack'] as $link ) {
|
||
|
|
if ( 'jetpack_admin_page' !== $link[1] ) {
|
||
|
|
return $offset;
|
||
|
|
}
|
||
|
|
$offset++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Refreshes the state cache via API call. Called via cron.
|
||
|
|
*/
|
||
|
|
public function refresh_state_cache() {
|
||
|
|
Jetpack_Core_Json_Api_Endpoints::get_scan_state();
|
||
|
|
Jetpack_Core_Json_Api_Endpoints::get_rewind_data();
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns true if the link should appear.
|
||
|
|
*
|
||
|
|
* @return boolean
|
||
|
|
*/
|
||
|
|
private function should_show_link() {
|
||
|
|
// Jetpack Scan/Backup is currently not supported on multisite.
|
||
|
|
if ( is_multisite() ) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check if VaultPress is active, the assumption there is that VaultPress is working.
|
||
|
|
// It has its link the adminbar.
|
||
|
|
if ( class_exists( 'VaultPress' ) ) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
return $this->has_backup() || $this->has_scan();
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Detects if Scan is enabled.
|
||
|
|
*
|
||
|
|
* @return boolean
|
||
|
|
*/
|
||
|
|
private function has_scan() {
|
||
|
|
$this->maybe_refresh_transient_cache();
|
||
|
|
$scan_state = get_transient( 'jetpack_scan_state' );
|
||
|
|
return ! $scan_state || 'unavailable' !== $scan_state->state;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Detects if Backup is enabled.
|
||
|
|
*
|
||
|
|
* @return boolean
|
||
|
|
*/
|
||
|
|
private function has_backup() {
|
||
|
|
$this->maybe_refresh_transient_cache();
|
||
|
|
$rewind_state = get_transient( 'jetpack_rewind_state' );
|
||
|
|
return ! $rewind_state || 'unavailable' !== $rewind_state->state;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Triggers a cron job to refresh the Scan and Rewind state cache.
|
||
|
|
*/
|
||
|
|
private function maybe_refresh_transient_cache() {
|
||
|
|
if ( $this->schedule_refresh_checked ) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Do we have a jetpack_scan and jetpack_rewind state set?
|
||
|
|
if ( get_transient( 'jetpack_scan_state' ) && get_transient( 'jetpack_rewind_state' ) ) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( false === wp_next_scheduled( self::SCHEDULE_ACTION_HOOK ) ) {
|
||
|
|
wp_schedule_single_event( time(), self::SCHEDULE_ACTION_HOOK );
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->schedule_refresh_checked = true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|