Completed
Push — fix/flickr-shortcode ( 3e5712...02d728 )
by
unknown
24:33 queued 14:33
created

Admin_Sidebar_Link::get_link_offset()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 0
dl 0
loc 10
rs 9.9332
c 0
b 0
f 0
1
<?php
2
/**
3
 * A class that adds a scan and backup link to the admin sidebar.
4
 *
5
 * @package automattic/jetpack
6
 */
7
8
namespace Automattic\Jetpack\Scan;
9
10
use Automattic\Jetpack\Redirect;
11
use Jetpack_Core_Json_Api_Endpoints;
12
13
/**
14
 * Class Main
15
 *
16
 * Responsible for showing the link if available.
17
 *
18
 * @package Automattic\Jetpack\Scan
19
 */
20
class Admin_Sidebar_Link {
21
22
	const SCHEDULE_ACTION_HOOK = 'jetpack_scan_refresh_states_event';
23
24
	/**
25
	 * The singleton instance of this class.
26
	 *
27
	 * @var Admin_Sidebar_Link
28
	 */
29
	protected static $instance;
30
31
	/**
32
	 * Used to check if we need to schedule the refresh or we need to do it.
33
	 *
34
	 * @var boolean | null
35
	 */
36
	private $schedule_refresh_checked;
37
38
	/**
39
	 * Get the singleton instance of the class.
40
	 *
41
	 * @return Admin_Sidebar_Link
42
	 */
43
	public static function instance() {
44
		if ( ! isset( self::$instance ) ) {
45
			self::$instance = new Admin_Sidebar_Link();
46
			self::$instance->init_hooks();
47
		}
48
49
		return self::$instance;
50
	}
51
52
	/**
53
	 * Adds action hooks.
54
	 */
55
	public function init_hooks() {
56
		add_action( 'jetpack_admin_menu', array( $this, 'maybe_add_admin_link' ), 99 );
57
		add_action( self::SCHEDULE_ACTION_HOOK, array( $this, 'refresh_state_cache' ) );
58
	}
59
60
	/**
61
	 * Adds a link to the Scan and Backup page.
62
	 */
63
	public function maybe_add_admin_link() {
64
		if ( ! $this->should_show_link() ) {
65
			return;
66
		}
67
68
		$new_link = $this->get_new_link();
69
70
		// Splice the nav menu item into the Jetpack nav.
71
		global $submenu;
72
		array_splice( $submenu['jetpack'], $this->get_link_offset(), 0, array( $new_link ) );
73
	}
74
75
	/**
76
	 * Retuns the new link.
77
	 *
78
	 *  @return array Link array to be added to the sidebar.
79
	 */
80
	private function get_new_link() {
81
		$has_scan   = $this->has_scan();
82
		$has_backup = $this->has_backup();
83
84
		$url = Redirect::get_url( 'calypso-backups' );
85
		if ( $has_scan && ! $has_backup ) {
86
			$menu_label = __( 'Scan', 'jetpack' );
87
			$url        = Redirect::get_url( 'calypso-scanner' );
88
		} elseif ( ! $has_scan && $has_backup ) {
89
			$menu_label = __( 'Backup', 'jetpack' );
90
		} else {
91
			// Will be both, as the code won't get this far if neither is true.
92
			$menu_label = __( 'Backup & Scan', 'jetpack' );
93
		}
94
95
		return array(
96
			esc_html( $menu_label ) . ' <span class="dashicons dashicons-external"></span>',
97
			'manage_options', // Check permissions here.
98
			esc_url( $url ),
99
		);
100
101
	}
102
103
	/**
104
	 * We create a menu offset by counting all the pages that have a jetpack_admin_page set as the link.
105
	 *
106
	 * This makes it so that the highlight of the pages works as expected. When you click on the Setting or Dashboard.
107
	 *
108
	 * @return int Menu offset.
109
	 */
110
	private function get_link_offset() {
111
		global $submenu;
112
		$offset = 0;
113
		foreach ( $submenu['jetpack'] as $link ) {
114
			if ( 'jetpack_admin_page' !== $link[1] ) {
115
				return $offset;
116
			}
117
			$offset++;
118
		}
119
	}
120
121
	/**
122
	 * Refreshes the state cache via API call. Called via cron.
123
	 */
124
	public function refresh_state_cache() {
125
		Jetpack_Core_Json_Api_Endpoints::get_scan_state();
126
		Jetpack_Core_Json_Api_Endpoints::get_rewind_data();
127
	}
128
129
	/**
130
	 * Returns true if the link should appear.
131
	 *
132
	 * @return boolean
133
	 */
134
	private function should_show_link() {
135
		// Jetpack Scan/Backup is currently not supported on multisite.
136
		if ( is_multisite() ) {
137
			return false;
138
		}
139
140
		// Check if VaultPress is active, the assumption there is that VaultPress is working.
141
		// It has its link the adminbar.
142
		if ( class_exists( 'VaultPress' ) ) {
143
			return false;
144
		}
145
146
		return $this->has_backup() || $this->has_scan();
147
	}
148
149
	/**
150
	 * Detects if Scan is enabled.
151
	 *
152
	 * @return boolean
153
	 */
154
	private function has_scan() {
155
		$this->maybe_refresh_transient_cache();
156
		$scan_state = get_transient( 'jetpack_scan_state' );
157
		return ! $scan_state || 'unavailable' !== $scan_state->state;
158
	}
159
160
	/**
161
	 * Detects if Backup is enabled.
162
	 *
163
	 * @return boolean
164
	 */
165
	private function has_backup() {
166
		$this->maybe_refresh_transient_cache();
167
		$rewind_state = get_transient( 'jetpack_rewind_state' );
168
		return ! $rewind_state || 'unavailable' !== $rewind_state->state;
169
	}
170
171
	/**
172
	 * Triggers a cron job to refresh the Scan and Rewind state cache.
173
	 */
174
	private function maybe_refresh_transient_cache() {
175
		if ( $this->schedule_refresh_checked ) {
176
			return;
177
		}
178
179
		// Do we have a jetpack_scan and jetpack_rewind state set?
180
		if ( get_transient( 'jetpack_scan_state' ) && get_transient( 'jetpack_rewind_state' ) ) {
181
			return;
182
		}
183
184
		if ( false === wp_next_scheduled( self::SCHEDULE_ACTION_HOOK ) ) {
185
			wp_schedule_single_event( time(), self::SCHEDULE_ACTION_HOOK );
186
		}
187
188
		$this->schedule_refresh_checked = true;
189
	}
190
}
191
192
193