Completed
Push — update/move_connection_owner_d... ( a0bfdc )
by
unknown
08:37
created

Post_Connection_JITM   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 317
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
dl 0
loc 317
rs 9.68
c 0
b 0
f 0
wmc 34
lcom 1
cbo 6

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A jitm_woocommerce_services_msg() 0 20 4
A jitm_jetpack_woo_services_install() 0 11 1
A jitm_jetpack_woo_services_activate() 0 11 1
A jitm_jetpack_creative_mail_install() 0 11 1
A jitm_jetpack_creative_mail_activate() 0 11 1
A delete_user_update_connection_owner_notice() 0 4 1
A dismiss() 0 11 1
F get_messages() 0 161 23
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\Connection\Client;
11
use Automattic\Jetpack\Connection\Manager;
12
use Automattic\Jetpack\Partner;
13
use Automattic\Jetpack\Redirect;
14
use Automattic\Jetpack\Tracking;
15
use Automattic\Jetpack\JITMS\JITM;
16
17
/**
18
 * Jetpack just in time messaging through out the admin
19
 *
20
 * @since 5.6.0
21
 */
22
class Post_Connection_JITM extends JITM {
23
24
	/**
25
	 * Tracking object.
26
	 *
27
	 * @var Automattic\Jetpack\Tracking
28
	 *
29
	 * @access private
30
	 */
31
	public $tracking;
32
33
	/**
34
	 * JITM constructor.
35
	 */
36
	public function __construct() {
37
		$this->tracking = new Tracking();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Automattic\Jetpack\Tracking() of type object<Automattic\Jetpack\Tracking> is incompatible with the declared type object<Automattic\Jetpac...attic\Jetpack\Tracking> of property $tracking.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
38
	}
39
40
	/**
41
	 * A special filter for WooCommerce, to set a message based on local state.
42
	 *
43
	 * @param string $content The current message.
44
	 *
45
	 * @return array The new message.
46
	 */
47
	public static function jitm_woocommerce_services_msg( $content ) {
48
		if ( ! function_exists( 'wc_get_base_location' ) ) {
49
			return $content;
50
		}
51
52
		$base_location = wc_get_base_location();
53
54
		switch ( $base_location['country'] ) {
55
			case 'US':
56
				$content->message = esc_html__( 'New free service: Show USPS shipping rates on your store! Added bonus: print shipping labels without leaving WooCommerce.', 'jetpack' );
57
				break;
58
			case 'CA':
59
				$content->message = esc_html__( 'New free service: Show Canada Post shipping rates on your store!', 'jetpack' );
60
				break;
61
			default:
62
				$content->message = '';
63
		}
64
65
		return $content;
66
	}
67
68
	/**
69
	 * A special filter for WooCommerce Call To Action button
70
	 *
71
	 * @return string The new CTA
72
	 */
73
	public static function jitm_jetpack_woo_services_install() {
74
		return wp_nonce_url(
75
			add_query_arg(
76
				array(
77
					'wc-services-action' => 'install',
78
				),
79
				admin_url( 'admin.php?page=wc-settings' )
80
			),
81
			'wc-services-install'
82
		);
83
	}
84
85
	/**
86
	 * A special filter for WooCommerce Call To Action button.
87
	 *
88
	 * @return string The new CTA
89
	 */
90
	public static function jitm_jetpack_woo_services_activate() {
91
		return wp_nonce_url(
92
			add_query_arg(
93
				array(
94
					'wc-services-action' => 'activate',
95
				),
96
				admin_url( 'admin.php?page=wc-settings' )
97
			),
98
			'wc-services-install'
99
		);
100
	}
101
102
	/**
103
	 * A special filter used in the CTA of a JITM offering to install the Creative Mail plugin.
104
	 *
105
	 * @return string The new CTA
106
	 */
107
	public static function jitm_jetpack_creative_mail_install() {
108
		return wp_nonce_url(
109
			add_query_arg(
110
				array(
111
					'creative-mail-action' => 'install',
112
				),
113
				admin_url( 'edit.php?post_type=feedback' )
114
			),
115
			'creative-mail-install'
116
		);
117
	}
118
119
	/**
120
	 * A special filter used in the CTA of a JITM offering to activate the Creative Mail plugin.
121
	 *
122
	 * @return string The new CTA
123
	 */
124
	public static function jitm_jetpack_creative_mail_activate() {
125
		return wp_nonce_url(
126
			add_query_arg(
127
				array(
128
					'creative-mail-action' => 'activate',
129
				),
130
				admin_url( 'edit.php?post_type=feedback' )
131
			),
132
			'creative-mail-install'
133
		);
134
	}
135
136
	/**
137
	 * This is an entire admin notice dedicated to messaging and handling of the case where a user is trying to delete
138
	 * the connection owner.
139
	 *
140
	 * @deprecated since version 9.0.0. Use Automattic\Jetpack\Connection\Owner::delete_user_update_connection_owner_notice instead.
141
	 */
142
	public function delete_user_update_connection_owner_notice() {
143
		deprecated_function( __METHOD__, 'jetpack-9.0.0', 'Automattic\\Jetpack\\Connection\\Owner::delete_user_update_connection_owner_notice' );
144
		return ( new Automattic\Jetpack\Connection\Owner() )->delete_user_update_connection_owner_notice();
145
	}
146
147
	/**
148
	 * Dismisses a JITM feature class so that it will no longer be shown.
149
	 *
150
	 * @param string $id The id of the JITM that was dismissed.
151
	 * @param string $feature_class The feature class of the JITM that was dismissed.
152
	 *
153
	 * @return bool Always true.
154
	 */
155
	public function dismiss( $id, $feature_class ) {
156
		$this->tracking->record_user_event(
157
			'jitm_dismiss_client',
158
			array(
159
				'jitm_id'       => $id,
160
				'feature_class' => $feature_class,
161
			)
162
		);
163
		$this->save_dismiss( $feature_class );
164
		return true;
165
	}
166
167
	/**
168
	 * Asks the wpcom API for the current message to display keyed on query string and message path
169
	 *
170
	 * @param string $message_path The message path to ask for.
171
	 * @param string $query The query string originally from the front end.
172
	 * @param bool   $full_jp_logo_exists If there is a full Jetpack logo already on the page.
173
	 *
174
	 * @return array The JITM's to show, or an empty array if there is nothing to show
175
	 */
176
	public function get_messages( $message_path, $query, $full_jp_logo_exists ) {
177
		// WooCommerce Services.
178
		add_filter( 'jitm_woocommerce_services_msg', array( $this, 'jitm_woocommerce_services_msg' ) );
179
		add_filter( 'jitm_jetpack_woo_services_install', array( $this, 'jitm_jetpack_woo_services_install' ) );
180
		add_filter( 'jitm_jetpack_woo_services_activate', array( $this, 'jitm_jetpack_woo_services_activate' ) );
181
182
		// Creative Mail.
183
		add_filter( 'jitm_jetpack_creative_mail_install', array( $this, 'jitm_jetpack_creative_mail_install' ) );
184
		add_filter( 'jitm_jetpack_creative_mail_activate', array( $this, 'jitm_jetpack_creative_mail_activate' ) );
185
186
		$user = wp_get_current_user();
187
188
		// Unauthenticated or invalid requests just bail.
189
		if ( ! $user ) {
190
			return array();
191
		}
192
193
		$user_roles = implode( ',', $user->roles );
194
		$site_id    = \Jetpack_Options::get_option( 'id' );
195
196
		// Build our jitm request.
197
		$path = add_query_arg(
198
			array(
199
				'external_user_id' => urlencode_deep( $user->ID ),
200
				'user_roles'       => urlencode_deep( $user_roles ),
201
				'query_string'     => urlencode_deep( $query ),
202
				'mobile_browser'   => jetpack_is_mobile( 'smart' ) ? 1 : 0,
203
				'_locale'          => get_user_locale(),
204
			),
205
			sprintf( '/sites/%d/jitm/%s', $site_id, $message_path )
206
		);
207
208
		// Attempt to get from cache.
209
		$envelopes = get_transient( 'jetpack_jitm_' . substr( md5( $path ), 0, 31 ) );
210
211
		// If something is in the cache and it was put in the cache after the last sync we care about, use it.
212
		$use_cache = false;
213
214
		/** This filter is documented in class.jetpack.php */
215
		if ( apply_filters( 'jetpack_just_in_time_msg_cache', false ) ) {
216
			$use_cache = true;
217
		}
218
219
		if ( $use_cache ) {
220
			$last_sync  = (int) get_transient( 'jetpack_last_plugin_sync' );
221
			$from_cache = $envelopes && $last_sync > 0 && $last_sync < $envelopes['last_response_time'];
222
		} else {
223
			$from_cache = false;
224
		}
225
226
		// Otherwise, ask again.
227
		if ( ! $from_cache ) {
228
			$wpcom_response = Client::wpcom_json_api_request_as_blog(
229
				$path,
230
				'2',
231
				array(
232
					'user_id'    => $user->ID,
233
					'user_roles' => implode( ',', $user->roles ),
234
				),
235
				null,
236
				'wpcom'
237
			);
238
239
			// silently fail...might be helpful to track it?
240
			if ( is_wp_error( $wpcom_response ) ) {
241
				return array();
242
			}
243
244
			$envelopes = json_decode( $wpcom_response['body'] );
245
246
			if ( ! is_array( $envelopes ) ) {
247
				return array();
248
			}
249
250
			$expiration = isset( $envelopes[0] ) ? $envelopes[0]->ttl : 300;
251
252
			// Do not cache if expiration is 0 or we're not using the cache.
253
			if ( 0 !== $expiration && $use_cache ) {
254
				$envelopes['last_response_time'] = time();
255
256
				set_transient( 'jetpack_jitm_' . substr( md5( $path ), 0, 31 ), $envelopes, $expiration );
257
			}
258
		}
259
260
		$hidden_jitms = \Jetpack_Options::get_option( 'hide_jitm' );
261
		unset( $envelopes['last_response_time'] );
262
263
		/**
264
		 * Allow adding your own custom JITMs after a set of JITMs has been received.
265
		 *
266
		 * @since 6.9.0
267
		 * @since 8.3.0 - Added Message path.
268
		 *
269
		 * @param array  $envelopes    array of existing JITMs.
270
		 * @param string $message_path The message path to ask for.
271
		 */
272
		$envelopes = apply_filters( 'jetpack_jitm_received_envelopes', $envelopes, $message_path );
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $message_path.

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...
273
274
		foreach ( $envelopes as $idx => &$envelope ) {
275
276
			$dismissed_feature = isset( $hidden_jitms[ $envelope->feature_class ] ) && is_array( $hidden_jitms[ $envelope->feature_class ] ) ? $hidden_jitms[ $envelope->feature_class ] : null;
277
278
			// If the this feature class has been dismissed and the request has not passed the ttl, skip it as it's been dismissed.
279
			if ( is_array( $dismissed_feature ) && ( time() - $dismissed_feature['last_dismissal'] < $envelope->expires || $dismissed_feature['number'] >= $envelope->max_dismissal ) ) {
280
				unset( $envelopes[ $idx ] );
281
				continue;
282
			}
283
284
			$this->tracking->record_user_event(
285
				'jitm_view_client',
286
				array(
287
					'jitm_id' => $envelope->id,
288
				)
289
			);
290
291
			$normalized_site_url = \Jetpack::build_raw_urls( get_home_url() );
292
293
			$url_params = array(
294
				'source' => "jitm-$envelope->id",
295
				'site'   => $normalized_site_url,
296
				'u'      => $user->ID,
297
			);
298
299
			// Get affiliate code and add it to the array of URL parameters.
300
			$aff = Partner::init()->get_partner_code( Partner::AFFILIATE_CODE );
301
			if ( '' !== $aff ) {
302
				$url_params['aff'] = $aff;
303
			}
304
305
			$envelope->url = add_query_arg( $url_params, 'https://jetpack.com/redirect/' );
306
307
			$envelope->jitm_stats_url = \Jetpack::build_stats_url( array( 'x_jetpack-jitm' => $envelope->id ) );
308
309
			// phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
310
			// $CTA is not valid per PHPCS, but it is part of the return from WordPress.com, so allowing.
311
			if ( $envelope->CTA->hook ) {
312
				$envelope->url = apply_filters( 'jitm_' . $envelope->CTA->hook, $envelope->url );
313
				unset( $envelope->CTA->hook );
314
			}
315
			// phpcs:enable
316
317
			if ( isset( $envelope->content->hook ) ) {
318
				$envelope->content = apply_filters( 'jitm_' . $envelope->content->hook, $envelope->content );
319
				unset( $envelope->content->hook );
320
			}
321
322
			// No point in showing an empty message.
323
			if ( empty( $envelope->content->message ) ) {
324
				unset( $envelopes[ $idx ] );
325
				continue;
326
			}
327
328
			$envelope->content->icon = $this->generate_icon( $envelope->content->icon, $full_jp_logo_exists );
329
330
			$jetpack = \Jetpack::init();
331
			$jetpack->stat( 'jitm', $envelope->id . '-viewed-' . JETPACK__VERSION );
332
			$jetpack->do_stats( 'server_side' );
333
		}
334
335
		return $envelopes;
336
	}
337
338
}
339