Completed
Push — update/add-single-purpose-jetp... ( 28d890...705f7e )
by
unknown
09:19
created

Tracking   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 247
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
dl 0
loc 247
rs 10
c 0
b 0
f 0
wmc 25
lcom 1
cbo 2

13 Methods

Rating   Name   Duplication   Size   Complexity  
A init() 0 30 2
A jetpack_activate_module() 0 3 1
A jetpack_deactivate_module() 0 3 1
A jetpack_user_authorized() 0 18 3
A jetpack_verify_secrets_begin() 0 3 1
A jetpack_verify_secrets_success() 0 3 1
A jetpack_verify_secrets_fail() 0 10 1
A wp_login_failed() 0 10 1
A jetpack_connection_register_fail() 0 6 1
A jetpack_connection_register_success() 0 5 1
A jetpack_xmlrpc_server_event() 0 16 3
A jetpack_verify_api_authorization_request_error_double_encode() 0 3 1
B wp_ajax_jetpack_tracks() 0 23 8
1
<?php
2
namespace Automattic\Jetpack\Plugin;
3
4
use Automattic\Jetpack\Tracking as Tracks;
5
use Automattic\Jetpack\Connection\Manager as Connection_Manager;
6
7
class Tracking {
8
	/**
9
	 * Tracking object.
10
	 *
11
	 * @var Tracks
12
	 *
13
	 * @access private
14
	 */
15
	private $tracking;
16
	/**
17
	 * Prevents the Tracking from being intialized more then once.
18
	 *
19
	 * @var bool
20
	 */
21
	private $initalized = false;
22
23
	public function init() {
24
		if ( $this->initalized ) {
25
			return;
26
		}
27
		$this->initalized = true;
28
		$this->tracking   = new Tracks( 'jetpack' );
29
30
		// For tracking stuff via js/ajax.
31
		add_action( 'admin_enqueue_scripts', array( $this->tracking, 'enqueue_tracks_scripts' ) );
32
33
		add_action( 'jetpack_activate_module', array( $this, 'jetpack_activate_module' ), 1, 1 );
34
		add_action( 'jetpack_deactivate_module', array( $this, 'jetpack_deactivate_module' ), 1, 1 );
35
		add_action( 'jetpack_user_authorized', array( $this, 'jetpack_user_authorized' ) );
36
		add_action( 'wp_login_failed', array( $this, 'wp_login_failed' ) );
37
38
		// Tracking XMLRPC server events.
39
		add_action( 'jetpack_xmlrpc_server_event', array( $this, 'jetpack_xmlrpc_server_event' ), 10, 4 );
40
41
		// Track that we've begun verifying the previously generated secret.
42
		add_action( 'jetpack_verify_secrets_begin', array( $this, 'jetpack_verify_secrets_begin' ), 10, 2 );
43
		add_action( 'jetpack_verify_secrets_success', array( $this, 'jetpack_verify_secrets_success' ), 10, 2 );
44
		add_action( 'jetpack_verify_secrets_fail', array( $this, 'jetpack_verify_secrets_fail' ), 10, 3 );
45
46
		// Universal ajax callback for all tracking events triggered via js.
47
		add_action( 'wp_ajax_jetpack_tracks', array( $this, 'wp_ajax_jetpack_tracks' ) );
48
49
		add_action( 'jetpack_verify_api_authorization_request_error_double_encode', array( $this, 'jetpack_verify_api_authorization_request_error_double_encode' ) );
50
		add_action( 'jetpack_connection_register_fail', array( $this, 'jetpack_connection_register_fail' ), 10, 2 );
51
		add_action( 'jetpack_connection_register_success', array( $this, 'jetpack_connection_register_success' ) );
52
	}
53
54
	/**
55
	 * Track that a specific module has been activated.
56
	 *
57
	 * @access public
58
	 *
59
	 * @param string $module Module slug.
60
	 */
61
	public function jetpack_activate_module( $module ) {
62
		$this->tracking->record_user_event( 'module_activated', array( 'module' => $module ) );
63
	}
64
65
	/**
66
	 * Track that a specific module has been deactivated.
67
	 *
68
	 * @access public
69
	 *
70
	 * @param string $module Module slug.
71
	 */
72
	public function jetpack_deactivate_module( $module ) {
73
		$this->tracking->record_user_event( 'module_deactivated', array( 'module' => $module ) );
74
	}
75
76
	/**
77
	 * Track that the user has successfully received an auth token.
78
	 *
79
	 * @access public
80
	 */
81
	public function jetpack_user_authorized() {
82
		$user_id = get_current_user_id();
83
		$anon_id = get_user_meta( $user_id, 'jetpack_tracks_anon_id', true );
84
85
		if ( $anon_id ) {
86
			$this->tracking->record_user_event( '_aliasUser', array( 'anonId' => $anon_id ) );
87
			delete_user_meta( $user_id, 'jetpack_tracks_anon_id' );
88
			if ( ! headers_sent() ) {
89
				setcookie( 'tk_ai', 'expired', time() - 1000 );
90
			}
91
		}
92
93
		$connection_manager = new Connection_Manager();
94
		$wpcom_user_data = $connection_manager->get_connected_user_data( $user_id );
95
		update_user_meta( $user_id, 'jetpack_tracks_wpcom_id', $wpcom_user_data['ID'] );
96
97
		$this->tracking->record_user_event( 'wpa_user_linked', array() );
98
	}
99
100
	/**
101
	 * Track that we've begun verifying the secrets.
102
	 *
103
	 * @access public
104
	 *
105
	 * @param string $action Type of secret (one of 'register', 'authorize', 'publicize').
106
	 * @param \WP_User $user The user object.
107
	 */
108
	public function jetpack_verify_secrets_begin( $action, $user ) {
109
		$this->tracking->record_user_event( "jpc_verify_{$action}_begin", array(), $user );
110
	}
111
112
	/**
113
	 * Track that we've succeeded in verifying the secrets.
114
	 *
115
	 * @access public
116
	 *
117
	 * @param string $action Type of secret (one of 'register', 'authorize', 'publicize').
118
	 * @param \WP_User $user The user object.
119
	 */
120
	public function jetpack_verify_secrets_success( $action, $user ) {
121
		$this->tracking->record_user_event( "jpc_verify_{$action}_success", array(), $user );
122
	}
123
124
	/**
125
	 * Track that we've failed verifying the secrets.
126
	 *
127
	 * @access public
128
	 *
129
	 * @param string $action Type of secret (one of 'register', 'authorize', 'publicize').
130
	 * @param \WP_User $user The user object.
131
	 * @param \WP_Error $error Error object.
132
	 */
133
	public function jetpack_verify_secrets_fail( $action, $user, $error ) {
134
		$this->tracking->record_user_event(
135
			"jpc_verify_{$action}_fail",
136
			array(
137
				'error_code'    => $error->get_error_code(),
0 ignored issues
show
Bug introduced by
The method get_error_code() does not seem to exist on object<WP_Error>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
138
				'error_message' => $error->get_error_message(),
0 ignored issues
show
Bug introduced by
The method get_error_message() does not seem to exist on object<WP_Error>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
139
			),
140
			$user
141
		);
142
	}
143
144
	/**
145
	 * Track a failed login attempt.
146
	 *
147
	 * @access public
148
	 *
149
	 * @param string $login Username or email address.
150
	 */
151
	public function wp_login_failed( $login ) {
152
		require_once JETPACK__PLUGIN_DIR . 'modules/protect/shared-functions.php';
153
		$this->tracking->record_user_event(
154
			'failed_login',
155
			array(
156
				'origin_ip' => jetpack_protect_get_ip(),
157
				'login'     => $login,
158
			)
159
		);
160
	}
161
162
	/**
163
	 * Track a connection failure at the registration step.
164
	 *
165
	 * @access public
166
	 *
167
	 * @param string|int $error      The error code.
168
	 * @param \WP_Error  $registered The error object.
169
	 */
170
	function jetpack_connection_register_fail( $error, $registered ) {
171
		$this->tracking->record_user_event( 'jpc_register_fail', array(
172
			'error_code'    => $error,
173
			'error_message' => $registered->get_error_message()
0 ignored issues
show
Bug introduced by
The method get_error_message() does not seem to exist on object<WP_Error>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
174
		) );
175
	}
176
177
	/**
178
	 * Track that the registration step of the connection has been successful.
179
	 *
180
	 * @access public
181
	 *
182
	 * @param string $from The 'from' GET parameter.
183
	 */
184
	function jetpack_connection_register_success( $from ) {
185
		$this->tracking->record_user_event( 'jpc_register_success', array(
186
			'from' => $from
187
		) );
188
	}
189
190
	/**
191
	 * Handles the jetpack_xmlrpc_server_event action that combines several types of events that
192
	 * happen during request serving.
193
	 *
194
	 * @param String                   $action the action name, i.e., 'remote_authorize'.
195
	 * @param String                   $stage  the execution stage, can be 'begin', 'success', 'error', etc.
196
	 * @param Array|WP_Error|IXR_Error $parameters (optional) extra parameters to be passed to the tracked action.
197
	 * @param WP_User                  $user (optional) the acting user.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $user not be WP_User|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
198
	 */
199
	public function jetpack_xmlrpc_server_event( $action, $stage, $parameters = array(), $user = null ) {
200
201
		if ( is_wp_error( $parameters ) ) {
202
			$parameters = array(
203
				'error_code'    => $parameters->get_error_code(),
204
				'error_message' => $parameters->get_error_message(),
205
			);
206
		} elseif ( is_a( $parameters, '\\IXR_Error' ) ) {
207
			$parameters = array(
208
				'error_code'    => $parameters->code,
209
				'error_message' => $parameters->message,
210
			);
211
		}
212
213
		$this->tracking->record_user_event( 'jpc_' . $action . '_' . $stage, $parameters, $user );
214
	}
215
216
	/**
217
	 * Track that the site is incorrectly double-encoding redirects from http to https.
218
	 *
219
	 * @access public
220
	 */
221
	function jetpack_verify_api_authorization_request_error_double_encode() {
222
		$this->tracking->record_user_event( 'error_double_encode' );
223
	}
224
225
	/**
226
	 * Universal method for for all tracking events triggered via the JavaScript client.
227
	 *
228
	 * @access public
229
	 */
230
	function wp_ajax_jetpack_tracks() {
231
		// Check for nonce
232
		if ( ! isset( $_REQUEST['tracksNonce'] ) || ! wp_verify_nonce( $_REQUEST['tracksNonce'], 'jp-tracks-ajax-nonce' ) ) {
233
			wp_die( 'Permissions check failed.' );
234
		}
235
236
		if ( ! isset( $_REQUEST['tracksEventName'] ) || ! isset( $_REQUEST['tracksEventType'] ) ) {
237
			wp_die( 'No valid event name or type.' );
238
		}
239
240
		$tracks_data = array();
241
		if ( 'click' === $_REQUEST['tracksEventType'] && isset( $_REQUEST['tracksEventProp'] ) ) {
242
			if ( is_array( $_REQUEST['tracksEventProp'] ) ) {
243
				$tracks_data = $_REQUEST['tracksEventProp'];
244
			} else {
245
				$tracks_data = array( 'clicked' => $_REQUEST['tracksEventProp'] );
246
			}
247
		}
248
249
		$this->tracking->record_user_event( $_REQUEST['tracksEventName'], $tracks_data );
250
		wp_send_json_success();
251
		wp_die();
252
	}
253
}
254