Completed
Push — add/scan-threat-notifications ( 52922c...a78046 )
by
unknown
100:14 queued 92:57
created

Admin_Bar_Notice::add_threats_to_toolbar()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 4
nop 1
dl 0
loc 30
rs 9.44
c 0
b 0
f 0
1
<?php
2
/**
3
 * A class that adds the scan notice to the admin bar.
4
 *
5
 * @package automattic/jetpack
6
 */
7
8
namespace Automattic\Jetpack\Scan;
9
10
use function Automattic\Jetpack\enqueue_async_script as jetpack_enqueue_async_script;
11
use Automattic\Jetpack\Redirect;
12
13
/**
14
 * Class Main
15
 *
16
 * Responsible for loading the admin bar notice if threats are found.
17
 *
18
 * @package Automattic\Jetpack\Scan
19
 */
20
class Admin_Bar_Notice {
21
	const SCRIPT_NAME    = 'jetpack-scan-show-notice';
22
	const SCRIPT_VERSION = '1';
23
24
	/**
25
	 * The singleton instance of this class.
26
	 *
27
	 * @var Admin_Bar_Notice
28
	 */
29
	protected static $instance;
30
31
	/**
32
	 * Get the singleton instance of the class.
33
	 *
34
	 * @return Admin_Bar_Notice
35
	 */
36
	public static function instance() {
37
		if ( ! isset( self::$instance ) ) {
38
			self::$instance = new Admin_Bar_Notice();
39
			self::$instance->init_hooks();
40
		}
41
42
		return self::$instance;
43
	}
44
	/**
45
	 * Initalize the hooks as needed.
46
	 */
47
	private function init_hooks() {
48
		if ( ! $this->should_try_to_display_notice() ) {
49
			return;
50
		}
51
52
		add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_toolbar_script' ) );
53
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_toolbar_script' ) );
54
		add_action( 'admin_bar_menu', array( $this, 'add_threats_to_toolbar' ), 999 );
55
	}
56
57
	/**
58
	 * Whether to even try to display the notice or now.
59
	 *
60
	 * @return bool
61
	 */
62
	private function should_try_to_display_notice() {
63
		if ( is_multisite() ) {
64
			return false; // Jetpack Scan is currently not supported on multisite.
65
		}
66
67
		// Check if VaultPress is active.
68
		if ( class_exists( 'VaultPress' ) ) {
69
			return false;
70
		}
71
72
		if ( ! current_user_can( 'manage_options' ) ) {
73
			return false; // Only show the notice to admins.
74
		}
75
76
		return true;
77
	}
78
79
	/**
80
	 * Add the inline styles and scripts if they are needed.
81
	 */
82
	public function enqueue_toolbar_script() {
83
		$this->add_inline_styles();
84
85
		if ( ! is_null( $this->has_threats() ) ) {
86
			return;
87
		}
88
89
		// We don't know about threats in the cache lets load the JS that fetches the info and updates the admin bar.
90
		jetpack_enqueue_async_script( self::SCRIPT_NAME, '_inc/build/scan/admin-bar-notice.min.js', 'modules/scan/admin-bar-notice.js', array(), self::SCRIPT_VERSION, true );
0 ignored issues
show
Documentation introduced by
self::SCRIPT_VERSION is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
91
92
		$script_data = array(
93
			'nonce'              => wp_create_nonce( 'wp_rest' ),
94
			'scan_endpoint'      => get_rest_url( null, 'jetpack/v4/scan' ),
95
			'scan_dashboard_url' => Redirect::get_url( 'calypso-scanner' ),
96
			/* translators: %s is the alert icon */
97
			'singular'           => sprintf( esc_html__( '%s Threat found', 'jetpack' ), $this->get_icon() ),
98
			/* translators: %s is the alert icon */
99
			'multiple'           => sprintf( esc_html__( '%s Threats found', 'jetpack' ), $this->get_icon() ),
100
		);
101
		wp_localize_script( self::SCRIPT_NAME, 'Jetpack_Scan', $script_data );
102
	}
103
104
	/**
105
	 * Adds the inline styles if they are needed.
106
	 */
107
	public function add_inline_styles() {
108
		// We know there are no threats so lets not include any css.
109
		if ( false === $this->has_threats() ) {
110
			return;
111
		}
112
113
		// We might be showing the threats in the admin bar lets make sure that they look great!
114
		$style = '#wp-admin-bar-jetpack-scan-notice svg { float:left; margin-top: 4px; margin-right: 6px; width: 18px; height: 22px; }';
115
		if ( is_rtl() ) {
116
			$style = '#wp-admin-bar-jetpack-scan-notice svg { float:right; margin-top: 4px; margin-left: 6px; width: 18px; height: 22px; }';
117
		}
118
		wp_add_inline_style( 'admin-bar', $style );
119
	}
120
121
	/**
122
	 * Add the link to the admin bar.
123
	 *
124
	 * @param WP_Admin_Bar $wp_admin_bar WP Admin Bar class object.
125
	 */
126
	public function add_threats_to_toolbar( $wp_admin_bar ) {
127
		if ( ! $this->should_try_to_display_notice() ) {
128
			return;
129
		}
130
131
		$has_threats = $this->has_threats();
132
		if ( false === $has_threats ) {
133
			return;
134
		}
135
136
		$node = array(
137
			'id'     => 'jetpack-scan-notice',
138
			'title'  => '',
139
			'parent' => 'top-secondary',
140
			'meta'   => array(
141
				'title' => esc_attr__( 'Visit your scan dashboard', 'jetpack' ),
142
				'class' => 'error',
143
			),
144
		);
145
146
		// No need to do anything...
147
		if ( $has_threats ) {
148
			/* translators: %s is the alert icon */
149
			$node['title']           = sprintf( esc_html__( '%s Threats found', 'jetpack' ), $this->get_icon() );
150
			$node['href']            = esc_url( Redirect::get_url( 'calypso-scanner' ) );
151
			$node['meta']['onclick'] = 'window.open( this.href ); return false;';
152
		}
153
154
		$wp_admin_bar->add_node( $node );
155
	}
156
157
	/**
158
	 * Returns the shield icon.
159
	 *
160
	 * @return string
161
	 */
162
	private function get_icon() {
163
		return '<svg width="18" height="22" viewBox="0 0 18 22" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9 0L0 4V10C0 15.55 3.84 20.74 9 22C14.16 20.74 18 15.55 18 10V4L9 0Z" fill="#D63638"/><path d="M7.99121 6.00894H10.0085V11.9968H7.99121V6.00894Z" fill="#FFF"/><path d="M7.99121 14.014H10.0085V15.9911H7.99121V14.014Z" fill="#FFF"/></svg>';
164
	}
165
166
	/**
167
	 *
168
	 * Return Whether boolean cached threats exist or null if the state is unknown.
169
	 * * @return boolean or null
170
	 */
171
	public function has_threats() {
172
		$scan_state = get_transient( 'jetpack_scan_state' );
173
		if ( empty( $scan_state ) ) {
174
			return null;
175
		}
176
177
		// Return true if there is at least one threat found.
178
		return (bool) isset( $scan_state->threats[0] );
179
	}
180
}
181