PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3
Jetpack – WP Security, Backup, Speed, & Growth v16.3
16.3 16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 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 All 508 releases
← All changes | jetpack_vendor/automattic/jetpack-jitm/src/class-post-connection-jitm.php +434 -0 16.2-beta → 16.3 View file →
@@ -1,0 +1,434 @@
1 +<?php
2 +/**
3 + * Jetpack's Post-Connection JITM class.
4 + *
5 + * @package automattic/jetpack-jitm
6 + */
7 +
8 +namespace Automattic\Jetpack\JITMS;
9 +
10 +use Automattic\Jetpack\A8c_Mc_Stats;
11 +use Automattic\Jetpack\Connection\Client;
12 +use Automattic\Jetpack\Connection\Manager;
13 +use Automattic\Jetpack\Device_Detection;
14 +use Automattic\Jetpack\Partner;
15 +use Automattic\Jetpack\Redirect;
16 +use Automattic\Jetpack\Tracking;
17 +
18 +if ( ! defined( 'ABSPATH' ) ) {
19 + exit( 0 );
20 +}
21 +
22 +/**
23 + * Jetpack just in time messaging through out the admin
24 + *
25 + * @since 1.1.0
26 + *
27 + * @since-jetpack 5.6.0
28 + */
29 +class Post_Connection_JITM extends JITM {
30 +
31 + /**
32 + * Tracking object.
33 + *
34 + * @var \Automattic\Jetpack\Tracking
35 + *
36 + * @access private
37 + */
38 + public $tracking;
39 +
40 + /**
41 + * JITM constructor.
42 + */
43 + public function __construct() {
44 + $this->tracking = new Tracking();
45 + }
46 +
47 + /**
48 + * A special filter for WooCommerce, to set a message based on local state.
49 + *
50 + * @param object $content The current message.
51 + *
52 + * @return object The new message.
53 + */
54 + public static function jitm_woocommerce_services_msg( $content ) {
55 + if ( ! function_exists( 'wc_get_base_location' ) ) {
56 + return $content;
57 + }
58 +
59 + $base_location = wc_get_base_location();
60 +
61 + switch ( $base_location['country'] ) {
62 + case 'US':
63 + $content->message = esc_html__( 'New free service: Show USPS shipping rates on your store! Added bonus: print shipping labels without leaving WooCommerce.', 'jetpack-jitm' );
64 + break;
65 + case 'CA':
66 + $content->message = esc_html__( 'New free service: Show Canada Post shipping rates on your store!', 'jetpack-jitm' );
67 + break;
68 + default:
69 + $content->message = '';
70 + }
71 +
72 + return $content;
73 + }
74 +
75 + /**
76 + * A special filter for WooCommerce Call To Action button
77 + *
78 + * @return string The new CTA
79 + */
80 + public static function jitm_jetpack_woo_services_install() {
81 + return wp_nonce_url(
82 + add_query_arg(
83 + array(
84 + 'wc-services-action' => 'install',
85 + ),
86 + admin_url( 'admin.php?page=wc-settings' )
87 + ),
88 + 'wc-services-install'
89 + );
90 + }
91 +
92 + /**
93 + * A special filter for WooCommerce Call To Action button.
94 + *
95 + * @return string The new CTA
96 + */
97 + public static function jitm_jetpack_woo_services_activate() {
98 + return wp_nonce_url(
99 + add_query_arg(
100 + array(
101 + 'wc-services-action' => 'activate',
102 + ),
103 + admin_url( 'admin.php?page=wc-settings' )
104 + ),
105 + 'wc-services-install'
106 + );
107 + }
108 +
109 + /**
110 + * A special filter used in the CTA of a JITM offering to install the Creative Mail plugin.
111 + *
112 + * @return string The new CTA
113 + */
114 + public static function jitm_jetpack_creative_mail_install() {
115 + return wp_nonce_url(
116 + add_query_arg(
117 + array(
118 + 'creative-mail-action' => 'install',
119 + ),
120 + admin_url( 'admin.php?page=jetpack-forms-admin' )
121 + ),
122 + 'creative-mail-install'
123 + );
124 + }
125 +
126 + /**
127 + * A special filter used in the CTA of a JITM offering to activate the Creative Mail plugin.
128 + *
129 + * @return string The new CTA
130 + */
131 + public static function jitm_jetpack_creative_mail_activate() {
132 + return wp_nonce_url(
133 + add_query_arg(
134 + array(
135 + 'creative-mail-action' => 'activate',
136 + ),
137 + admin_url( 'admin.php?page=jetpack-forms-admin' )
138 + ),
139 + 'creative-mail-install'
140 + );
141 + }
142 +
143 + /**
144 + * A special filter used in the CTA of a JITM offering to install the Jetpack Backup plugin.
145 + *
146 + * @return string The new CTA
147 + */
148 + public static function jitm_jetpack_backup_install() {
149 + return wp_nonce_url(
150 + add_query_arg(
151 + array(
152 + 'jetpack-backup-action' => 'install',
153 + ),
154 + admin_url( 'admin.php?page=jetpack' )
155 + ),
156 + 'jetpack-backup-install'
157 + );
158 + }
159 +
160 + /**
161 + * A special filter used in the CTA of a JITM offering to activate the Jetpack Backup plugin.
162 + *
163 + * @return string The new CTA
164 + */
165 + public static function jitm_jetpack_backup_activate() {
166 + return wp_nonce_url(
167 + add_query_arg(
168 + array(
169 + 'jetpack-backup-action' => 'activate',
170 + ),
171 + admin_url( 'admin.php?page=jetpack' )
172 + ),
173 + 'jetpack-backup-install'
174 + );
175 + }
176 +
177 + /**
178 + * A special filter used in the CTA of a JITM offering to install the Jetpack Boost plugin.
179 + *
180 + * @return string The new CTA
181 + */
182 + public static function jitm_jetpack_boost_install() {
183 + return wp_nonce_url(
184 + add_query_arg(
185 + array(
186 + 'jetpack-boost-action' => 'install',
187 + ),
188 + admin_url( 'admin.php?page=jetpack' )
189 + ),
190 + 'jetpack-boost-install'
191 + );
192 + }
193 +
194 + /**
195 + * A special filter used in the CTA of a JITM offering to activate the Jetpack Boost plugin.
196 + *
197 + * @return string The new CTA
198 + */
199 + public static function jitm_jetpack_boost_activate() {
200 + return wp_nonce_url(
201 + add_query_arg(
202 + array(
203 + 'jetpack-boost-action' => 'activate',
204 + ),
205 + admin_url( 'admin.php?page=jetpack' )
206 + ),
207 + 'jetpack-boost-install'
208 + );
209 + }
210 +
211 + /**
212 + * Dismisses a JITM feature class so that it will no longer be shown.
213 + *
214 + * @param string $id The id of the JITM that was dismissed.
215 + * @param string $feature_class The feature class of the JITM that was dismissed.
216 + *
217 + * @return bool Always true.
218 + */
219 + public function dismiss( $id, $feature_class ) {
220 + $this->tracking->record_user_event(
221 + 'jitm_dismiss_client',
222 + array(
223 + 'jitm_id' => $id,
224 + 'feature_class' => $feature_class,
225 + )
226 + );
227 + $this->save_dismiss( $feature_class );
228 + return true;
229 + }
230 +
231 + /**
232 + * Asks the wpcom API for the current message to display keyed on query string and message path.
233 + *
234 + * For sites running on the Dotcom Simple codebase, the network request is bypassed
235 + * via Client::wpcom_json_api_request_as_blog allowing for the JITM\Engine to be called
236 + * directly.
237 + *
238 + * @param string $message_path The message path to ask for.
239 + * @param array $query Query parameters as an associative array.
240 + * @param bool $full_jp_logo_exists If there is a full Jetpack logo already on the page.
241 + *
242 + * @return array The JITM's to show, or an empty array if there is nothing to show
243 + */
244 + public function get_messages( $message_path, $query, $full_jp_logo_exists ) {
245 + // WooCommerce Services.
246 + add_filter( 'jitm_woocommerce_services_msg', array( $this, 'jitm_woocommerce_services_msg' ) );
247 + add_filter( 'jitm_jetpack_woo_services_install', array( $this, 'jitm_jetpack_woo_services_install' ) );
248 + add_filter( 'jitm_jetpack_woo_services_activate', array( $this, 'jitm_jetpack_woo_services_activate' ) );
249 +
250 + // Creative Mail.
251 + add_filter( 'jitm_jetpack_creative_mail_install', array( $this, 'jitm_jetpack_creative_mail_install' ) );
252 + add_filter( 'jitm_jetpack_creative_mail_activate', array( $this, 'jitm_jetpack_creative_mail_activate' ) );
253 +
254 + // Jetpack Backup.
255 + add_filter( 'jitm_jetpack_backup_install', array( $this, 'jitm_jetpack_backup_install' ) );
256 + add_filter( 'jitm_jetpack_backup_activate', array( $this, 'jitm_jetpack_backup_activate' ) );
257 +
258 + // Jetpack Boost.
259 + add_filter( 'jitm_jetpack_boost_install', array( $this, 'jitm_jetpack_boost_install' ) );
260 + add_filter( 'jitm_jetpack_boost_activate', array( $this, 'jitm_jetpack_boost_activate' ) );
261 +
262 + $user = wp_get_current_user();
263 +
264 + // Unauthenticated or invalid requests just bail.
265 + if ( ! $user ) {
266 + return array();
267 + }
268 +
269 + $user_roles = implode( ',', $user->roles );
270 + $site_id = \Jetpack_Options::get_option( 'id' );
271 +
272 + // Build our jitm request.
273 + $path = add_query_arg(
274 + array(
275 + 'external_user_id' => urlencode_deep( $user->ID ),
276 + 'user_roles' => urlencode_deep( $user_roles ),
277 + 'query_string' => urlencode_deep( build_query( $query ) ),
278 + 'mobile_browser' => Device_Detection::is_smartphone() ? 1 : 0,
279 + '_locale' => get_user_locale(),
280 + ),
281 + sprintf( '/sites/%d/jitm/%s', $site_id, $message_path )
282 + );
283 +
284 + $cache_key = 'jetpack_jitm_' . substr( md5( $path ), 0, 31 );
285 +
286 + // Attempt to get from cache.
287 + $envelopes = get_transient( $cache_key );
288 +
289 + // If something is in the cache and it was put in the cache after the last sync we care about, use it.
290 + $use_cache = false;
291 +
292 + /**
293 + * Filter to turn off jitm caching
294 + *
295 + * @since 1.1.0
296 + * @since-jetpack 5.4.0
297 + *
298 + * @param bool true Whether to cache just in time messages
299 + */
300 + if ( apply_filters( 'jetpack_just_in_time_msg_cache', true ) ) {
301 + $use_cache = true;
302 + }
303 +
304 + if ( $use_cache ) {
305 + $last_sync = (int) get_transient( 'jetpack_last_plugin_sync' );
306 + // The sync timestamp indicates when a plugin change was last sent to Jetpack, however,
307 + // it's stored in a transient and doesn't stay forever. Therefore, an admin who last changed
308 + // a plugin a month ago is likely to have $last_sync=0.
309 + //
310 + // If the sync timestamp is missing (value 0): use the cache.
311 + // If the timestamp exists and is older than the cached envelope: use the cache.
312 + // If the timestamp exists and is newer: bypass and refresh.
313 + // (This case means the JITM was created before the last plugin activate/deactivate and is invalid).
314 + $from_cache = $envelopes && ( 0 === $last_sync || $last_sync < $envelopes['last_response_time'] );
315 + } else {
316 + $from_cache = false;
317 + }
318 +
319 + // Otherwise, ask again.
320 + if ( ! $from_cache ) {
321 + $wpcom_response = Client::wpcom_json_api_request_as_blog(
322 + $path,
323 + '2',
324 + array(
325 + 'user_id' => $user->ID,
326 + 'user_roles' => implode( ',', $user->roles ),
327 + ),
328 + null,
329 + 'wpcom'
330 + );
331 +
332 + // silently fail...might be helpful to track it?
333 + if ( is_wp_error( $wpcom_response ) ) {
334 + return array();
335 + }
336 +
337 + $envelopes = json_decode( $wpcom_response['body'] );
338 +
339 + if ( ! is_array( $envelopes ) ) {
340 + return array();
341 + }
342 +
343 + $expiration = isset( $envelopes[0] ) ? $envelopes[0]->ttl : 300;
344 +
345 + // Do not cache if expiration is 0 or we're not using the cache.
346 + if ( 0 !== $expiration && $use_cache ) {
347 + $envelopes['last_response_time'] = time();
348 + set_transient( $cache_key, $envelopes, $expiration );
349 + }
350 + }
351 +
352 + $hidden_jitms = \Jetpack_Options::get_option( 'hide_jitm' );
353 + unset( $envelopes['last_response_time'] );
354 +
355 + /**
356 + * Allow adding your own custom JITMs after a set of JITMs has been received.
357 + *
358 + * @since 1.1.0
359 + * @since-jetpack 6.9.0
360 + * @since-jetpack 8.3.0 - Added Message path.
361 + *
362 + * @param array $envelopes array of existing JITMs.
363 + * @param string $message_path The message path to ask for.
364 + */
365 + $envelopes = apply_filters( 'jetpack_jitm_received_envelopes', $envelopes, $message_path );
366 +
367 + foreach ( $envelopes as $idx => &$envelope ) {
368 +
369 + $dismissed_feature = isset( $hidden_jitms[ $envelope->feature_class ] ) && is_array( $hidden_jitms[ $envelope->feature_class ] ) ? $hidden_jitms[ $envelope->feature_class ] : null;
370 +
371 + // If the this feature class has been dismissed and the request has not passed the ttl, skip it as it's been dismissed.
372 + if ( is_array( $dismissed_feature ) && ( time() - $dismissed_feature['last_dismissal'] < $envelope->expires || $dismissed_feature['number'] >= $envelope->max_dismissal ) ) {
373 + unset( $envelopes[ $idx ] );
374 + continue;
375 + }
376 +
377 + $this->tracking->record_user_event(
378 + 'jitm_view_client',
379 + array(
380 + 'jitm_id' => $envelope->id,
381 + 'jitm_message_path' => $message_path,
382 + )
383 + );
384 +
385 + $url_params = array(
386 + 'u' => $user->ID,
387 + );
388 +
389 + // Get affiliate code and add it to the array of URL parameters.
390 + $aff = Partner::init()->get_partner_code( Partner::AFFILIATE_CODE );
391 + if ( '' !== $aff ) {
392 + $url_params['aff'] = $aff;
393 + }
394 +
395 + // Check if the current user has connected their WP.com account
396 + // and if not add this information to the the array of URL parameters.
397 + if ( ! ( new Manager() )->is_user_connected( $user->ID ) ) {
398 + $url_params['query'] = 'unlinked=1';
399 + }
400 + $envelope->url = esc_url( Redirect::get_url( "jitm-$envelope->id", $url_params ) );
401 +
402 + $stats = new A8c_Mc_Stats();
403 +
404 + $envelope->jitm_stats_url = $stats->build_stats_url( array( 'x_jetpack-jitm' => $envelope->id ) );
405 +
406 + // phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
407 + // $CTA is not valid per PHPCS, but it is part of the return from WordPress.com, so allowing.
408 + if ( $envelope->CTA->hook ) {
409 + $envelope->url = apply_filters( 'jitm_' . $envelope->CTA->hook, $envelope->url );
410 + unset( $envelope->CTA->hook );
411 + }
412 + // phpcs:enable
413 +
414 + if ( isset( $envelope->content->hook ) ) {
415 + $envelope->content = apply_filters( 'jitm_' . $envelope->content->hook, $envelope->content );
416 + unset( $envelope->content->hook );
417 + }
418 +
419 + // No point in showing an empty message.
420 + if ( empty( $envelope->content->message ) ) {
421 + unset( $envelopes[ $idx ] );
422 + continue;
423 + }
424 +
425 + $envelope->content->icon = $this->generate_icon( $envelope->content->icon, $full_jp_logo_exists );
426 + $envelope->message_path = esc_attr( $message_path );
427 +
428 + $stats->add( 'jitm', $envelope->id . '-viewed' );
429 + $stats->do_server_side_stats();
430 + }
431 +
432 + return $envelopes;
433 + }
434 +}