Completed
Push — update/remove-userless-jargon ( 8c94d4...0520f9 )
by
unknown
545:18 queued 534:20
created

JITM::jetpack_track_last_sync_callback()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
nc 4
nop 1
dl 0
loc 18
rs 9.3554
c 0
b 0
f 0
1
<?php
2
/**
3
 * Jetpack's JITM class.
4
 *
5
 * @package automattic/jetpack-jitm
6
 */
7
8
namespace Automattic\Jetpack\JITMS;
9
10
use Automattic\Jetpack\Assets;
11
use Automattic\Jetpack\Assets\Logo as Jetpack_Logo;
12
use Automattic\Jetpack\Connection\Manager as Connection_Manager;
13
use Automattic\Jetpack\Status;
14
15
/**
16
 * Jetpack just in time messaging through out the admin
17
 *
18
 * @since 5.6.0
19
 */
20
class JITM {
21
22
	const PACKAGE_VERSION = '1.15.2-alpha';
23
24
	/**
25
	 * Whether the JITMs have been registered.
26
	 *
27
	 * @var bool
28
	 */
29
	private static $jitms_registered = false;
30
31
	/**
32
	 * The configuration method that is called from the jetpack-config package.
33
	 */
34
	public static function configure() {
35
		$jitm = self::get_instance();
36
		$jitm->register();
37
	}
38
39
	/**
40
	 * Pre/Post Connection JITM factory metod
41
	 *
42
	 * @return Post_Connection_JITM|Pre_Connection_JITM JITM instance.
43
	 */
44
	public static function get_instance() {
45
		if ( ( new Connection_Manager() )->is_connected() ) {
46
			$jitm = new Post_Connection_JITM();
47
		} else {
48
			$jitm = new Pre_Connection_JITM();
49
		}
50
		return $jitm;
51
	}
52
53
	/**
54
	 * Sets up JITM action callbacks if needed.
55
	 */
56
	public function register() {
57
		if ( self::$jitms_registered ) {
58
			// JITMs have already been registered.
59
			return;
60
		}
61
62
		self::$jitms_registered = true;
63
64
		if ( ! $this->jitms_enabled() ) {
65
			// Do nothing.
66
			return;
67
		}
68
69
		add_action( 'rest_api_init', array( __NAMESPACE__ . '\\Rest_Api_Endpoints', 'register_endpoints' ) );
70
71
		add_action( 'current_screen', array( $this, 'prepare_jitms' ) );
72
73
		/**
74
		 * These are sync actions that we need to keep track of for jitms.
75
		 */
76
		add_filter( 'jetpack_sync_before_send_updated_option', array( $this, 'jetpack_track_last_sync_callback' ), 99 );
77
	}
78
79
	/**
80
	 * Checks the jetpack_just_in_time_msgs filters and whether the site
81
	 * is offline to determine whether JITMs are enabled.
82
	 *
83
	 * @return bool True if JITMs are enabled, else false.
84
	 */
85
	public function jitms_enabled() {
86
		/**
87
		 * Filter to turn off all just in time messages
88
		 *
89
		 * @since 3.7.0
90
		 * @since 5.4.0 Correct docblock to reflect default arg value
91
		 *
92
		 * @param bool true Whether to show just in time messages.
93
		 */
94
		if ( ! apply_filters( 'jetpack_just_in_time_msgs', true ) ) {
95
			return false;
96
		}
97
98
		// Folks cannot connect to WordPress.com and won't really be able to act on the pre-connection messages. So bail.
99
		if ( ( new Status() )->is_offline_mode() ) {
100
			return false;
101
		}
102
103
		return true;
104
	}
105
106
	/**
107
	 * Prepare actions according to screen and post type.
108
	 *
109
	 * @since 3.8.2
110
	 *
111
	 * @uses Jetpack_Autoupdate::get_possible_failures()
112
	 *
113
	 * @param \WP_Screen $screen WP Core's screen object.
114
	 */
115
	public function prepare_jitms( $screen ) {
116
		/**
117
		 * Filter to hide JITMs on certain screens.
118
		 *
119
		 * @since 9.5.0
120
		 *
121
		 * @param bool true Whether to show just in time messages.
122
		 * @param string $string->id The ID of the current screen.
123
		 */
124
		if ( apply_filters( 'jetpack_display_jitms_on_screen', true, $screen->id ) ) {
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $screen->id.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
125
			add_action( 'admin_enqueue_scripts', array( $this, 'jitm_enqueue_files' ) );
126
			add_action( 'admin_notices', array( $this, 'ajax_message' ) );
127
			add_action( 'edit_form_top', array( $this, 'ajax_message' ) );
128
		}
129
	}
130
131
	/**
132
	 * Function to enqueue jitm css and js
133
	 */
134
	public function jitm_enqueue_files() {
135
		if ( $this->is_gutenberg_page() ) {
136
			return;
137
		}
138
		$min = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
139
		wp_register_style(
140
			'jetpack-jitm-css',
141
			plugins_url( "css/jetpack-admin-jitm{$min}.css", __FILE__ ),
142
			false,
143
			self::PACKAGE_VERSION .
144
			'-201243242'
145
		);
146
		wp_style_add_data( 'jetpack-jitm-css', 'rtl', 'replace' );
147
		wp_style_add_data( 'jetpack-jitm-css', 'suffix', $min );
148
		wp_enqueue_style( 'jetpack-jitm-css' );
149
150
		wp_enqueue_script(
151
			'jetpack-jitm-new',
152
			Assets::get_file_url_for_environment( 'js/jetpack-jitm.min.js', 'js/jetpack-jitm.js', __FILE__ ),
153
			array( 'jquery' ),
154
			self::PACKAGE_VERSION,
155
			true
156
		);
157
		wp_localize_script(
158
			'jetpack-jitm-new',
159
			'jitm_config',
160
			array(
161
				'api_root'               => esc_url_raw( rest_url() ),
162
				'activate_module_text'   => esc_html__( 'Activate', 'jetpack' ),
163
				'activated_module_text'  => esc_html__( 'Activated', 'jetpack' ),
164
				'activating_module_text' => esc_html__( 'Activating', 'jetpack' ),
165
				'nonce'                  => wp_create_nonce( 'wp_rest' ),
166
			)
167
		);
168
	}
169
170
	/**
171
	 * Is the current page a block editor page?
172
	 *
173
	 * @since 8.0.0
174
	 */
175
	public function is_gutenberg_page() {
176
		$current_screen = get_current_screen();
177
		return ( method_exists( $current_screen, 'is_block_editor' ) && $current_screen->is_block_editor() );
178
	}
179
180
	/**
181
	 * Get's the current message path for display of a JITM
182
	 *
183
	 * @return string The message path
184
	 */
185
	public function get_message_path() {
186
		$screen = get_current_screen();
187
188
		return 'wp:' . $screen->id . ':' . current_filter();
189
	}
190
191
	/**
192
	 * Injects the dom to show a JITM inside of wp-admin.
193
	 */
194
	public function ajax_message() {
195
		if ( ! is_admin() ) {
196
			return;
197
		}
198
199
		// do not display on Gutenberg pages.
200
		if ( $this->is_gutenberg_page() ) {
201
			return;
202
		}
203
204
		$message_path   = $this->get_message_path();
205
		$query_string   = _http_build_query( $_GET, '', ',' ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
206
		$current_screen = wp_unslash( $_SERVER['REQUEST_URI'] );
207
		?>
208
		<div class="jetpack-jitm-message"
209
			data-nonce="<?php echo esc_attr( wp_create_nonce( 'wp_rest' ) ); ?>"
210
			data-ajax-nonce="<?php echo esc_attr( wp_create_nonce( 'wp_ajax_action' ) ); ?>"
211
			data-message-path="<?php echo esc_attr( $message_path ); ?>"
212
			data-query="<?php echo urlencode_deep( $query_string ); ?>"
213
			data-redirect="<?php echo urlencode_deep( $current_screen ); ?>"
214
		></div>
215
		<?php
216
	}
217
218
	/**
219
	 * Generate the icon to display on the JITM
220
	 *
221
	 * @param string $content_icon Icon type name.
222
	 * @param bool   $full_jp_logo_exists Is there a big JP logo already displayed on this screen.
223
	 */
224
	public function generate_icon( $content_icon, $full_jp_logo_exists ) {
225
		switch ( $content_icon ) {
226
			case 'jetpack':
227
				$jetpack_logo = new Jetpack_Logo();
228
				$content_icon = '<div class="jp-emblem">' . ( ( $full_jp_logo_exists ) ? $jetpack_logo->get_jp_emblem() : $jetpack_logo->get_jp_emblem_larger() ) . '</div>';
229
				break;
230
			case 'woocommerce':
231
				$content_icon = '<div class="jp-emblem"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 168 100" xml:space="preserve" enable-background="new 0 0 168 100" width="50" height="30"><style type="text/css">
232
				.st0{clip-path:url(#SVGID_2_);enable-background:new    ;}
233
				.st1{clip-path:url(#SVGID_4_);}
234
				.st2{clip-path:url(#SVGID_6_);}
235
				.st3{clip-path:url(#SVGID_8_);fill:#8F567F;}
236
				.st4{clip-path:url(#SVGID_10_);fill:#FFFFFE;}
237
				.st5{clip-path:url(#SVGID_12_);fill:#FFFFFE;}
238
				.st6{clip-path:url(#SVGID_14_);fill:#FFFFFE;}
239
			</style><g><defs><polygon id="SVGID_1_" points="83.8 100 0 100 0 0.3 83.8 0.3 167.6 0.3 167.6 100 "/></defs><clipPath id="SVGID_2_"><use xlink:href="#SVGID_1_" overflow="visible"/></clipPath><g class="st0"><g><defs><rect id="SVGID_3_" width="168" height="100"/></defs><clipPath id="SVGID_4_"><use xlink:href="#SVGID_3_" overflow="visible"/></clipPath><g class="st1"><defs><path id="SVGID_5_" d="M15.6 0.3H152c8.6 0 15.6 7 15.6 15.6v52c0 8.6-7 15.6-15.6 15.6h-48.9l6.7 16.4L80.2 83.6H15.6C7 83.6 0 76.6 0 67.9v-52C0 7.3 7 0.3 15.6 0.3"/></defs><clipPath id="SVGID_6_"><use xlink:href="#SVGID_5_" overflow="visible"/></clipPath><g class="st2"><defs><rect id="SVGID_7_" width="168" height="100"/></defs><clipPath id="SVGID_8_"><use xlink:href="#SVGID_7_" overflow="visible"/></clipPath><rect x="-10" y="-9.7" class="st3" width="187.6" height="119.7"/></g></g></g></g></g><g><defs><path id="SVGID_9_" d="M8.4 14.5c1-1.3 2.4-2 4.3-2.1 3.5-0.2 5.5 1.4 6 4.9 2.1 14.3 4.4 26.4 6.9 36.4l15-28.6c1.4-2.6 3.1-3.9 5.2-4.1 3-0.2 4.9 1.7 5.6 5.7 1.7 9.1 3.9 16.9 6.5 23.4 1.8-17.4 4.8-30 9-37.7 1-1.9 2.5-2.9 4.5-3 1.6-0.1 3 0.3 4.3 1.4 1.3 1 2 2.3 2.1 3.9 0.1 1.2-0.1 2.3-0.7 3.3 -2.7 5-4.9 13.2-6.6 24.7 -1.7 11.1-2.3 19.8-1.9 26.1 0.1 1.7-0.1 3.2-0.8 4.5 -0.8 1.5-2 2.4-3.7 2.5 -1.8 0.1-3.6-0.7-5.4-2.5C52.4 66.7 47.4 57 43.7 44.1c-4.4 8.8-7.7 15.3-9.9 19.7 -4 7.7-7.5 11.7-10.3 11.9 -1.9 0.1-3.5-1.4-4.8-4.7 -3.5-9-7.3-26.3-11.3-52C7.1 17.3 7.5 15.8 8.4 14.5"/></defs><clipPath id="SVGID_10_"><use xlink:href="#SVGID_9_" overflow="visible"/></clipPath><rect x="-2.7" y="-0.6" class="st4" width="90.6" height="86.4"/></g><g><defs><path id="SVGID_11_" d="M155.6 25.2c-2.5-4.3-6.1-6.9-11-7.9 -1.3-0.3-2.5-0.4-3.7-0.4 -6.6 0-11.9 3.4-16.1 10.2 -3.6 5.8-5.3 12.3-5.3 19.3 0 5.3 1.1 9.8 3.3 13.6 2.5 4.3 6.1 6.9 11 7.9 1.3 0.3 2.5 0.4 3.7 0.4 6.6 0 12-3.4 16.1-10.2 3.6-5.9 5.3-12.4 5.3-19.4C159 33.4 157.9 28.9 155.6 25.2zM147 44.2c-0.9 4.5-2.7 7.9-5.2 10.1 -2 1.8-3.9 2.5-5.5 2.2 -1.7-0.3-3-1.8-4-4.4 -0.8-2.1-1.2-4.2-1.2-6.2 0-1.7 0.2-3.4 0.5-5 0.6-2.8 1.8-5.5 3.6-8.1 2.3-3.3 4.7-4.8 7.1-4.2 1.7 0.3 3 1.8 4 4.4 0.8 2.1 1.2 4.2 1.2 6.2C147.5 40.9 147.3 42.6 147 44.2z"/></defs><clipPath id="SVGID_12_"><use xlink:href="#SVGID_11_" overflow="visible"/></clipPath><rect x="109.6" y="6.9" class="st5" width="59.4" height="71.4"/></g><g><defs><path id="SVGID_13_" d="M112.7 25.2c-2.5-4.3-6.1-6.9-11-7.9 -1.3-0.3-2.5-0.4-3.7-0.4 -6.6 0-11.9 3.4-16.1 10.2 -3.5 5.8-5.3 12.3-5.3 19.3 0 5.3 1.1 9.8 3.3 13.6 2.5 4.3 6.1 6.9 11 7.9 1.3 0.3 2.5 0.4 3.7 0.4 6.6 0 12-3.4 16.1-10.2 3.5-5.9 5.3-12.4 5.3-19.4C116 33.4 114.9 28.9 112.7 25.2zM104.1 44.2c-0.9 4.5-2.7 7.9-5.2 10.1 -2 1.8-3.9 2.5-5.5 2.2 -1.7-0.3-3-1.8-4-4.4 -0.8-2.1-1.2-4.2-1.2-6.2 0-1.7 0.2-3.4 0.5-5 0.6-2.8 1.8-5.5 3.6-8.1 2.3-3.3 4.7-4.8 7.1-4.2 1.7 0.3 3 1.8 4 4.4 0.8 2.1 1.2 4.2 1.2 6.2C104.6 40.9 104.4 42.6 104.1 44.2z"/></defs><clipPath id="SVGID_14_"><use xlink:href="#SVGID_13_" overflow="visible"/></clipPath><rect x="66.7" y="6.9" class="st6" width="59.4" height="71.4"/></g></svg></div>';
240
				break;
241
			default:
242
				$content_icon = '';
243
				break;
244
		}
245
		return $content_icon;
246
	}
247
248
	/**
249
	 * Stores dismiss data into an option
250
	 *
251
	 * @param string $key Dismiss key.
252
	 */
253
	public function save_dismiss( $key ) {
254
		$hide_jitm = \Jetpack_Options::get_option( 'hide_jitm' );
255
		if ( ! is_array( $hide_jitm ) ) {
256
			$hide_jitm = array();
257
		}
258
259
		if ( ! isset( $hide_jitm[ $key ] ) || ! is_array( $hide_jitm[ $key ] ) ) {
260
			$hide_jitm[ $key ] = array(
261
				'last_dismissal' => 0,
262
				'number'         => 0,
263
			);
264
		}
265
266
		$hide_jitm[ $key ] = array(
267
			'last_dismissal' => time(),
268
			'number'         => $hide_jitm[ $key ]['number'] + 1,
269
		);
270
271
		\Jetpack_Options::update_option( 'hide_jitm', $hide_jitm );
272
	}
273
274
	/**
275
	 * Sets the 'jetpack_last_plugin_sync' transient when the active_plugins option is synced.
276
	 *
277
	 * @param array $params The action parameters.
278
	 *
279
	 * @return array Returns the action parameters unchanged.
280
	 */
281
	public function jetpack_track_last_sync_callback( $params ) {
282
		/**
283
		 * This filter is documented in the Automattic\Jetpack\JITMS\Post_Connection_JITM class.
284
		 */
285
		if ( ! apply_filters( 'jetpack_just_in_time_msg_cache', true ) ) {
286
			return $params;
287
		}
288
289
		if ( is_array( $params ) && isset( $params[0] ) ) {
290
			$option = $params[0];
291
			if ( 'active_plugins' === $option ) {
292
				// Use the cache if we can, but not terribly important if it gets evicted.
293
				set_transient( 'jetpack_last_plugin_sync', time(), HOUR_IN_SECONDS );
294
			}
295
		}
296
297
		return $params;
298
	}
299
}
300