Completed
Push — gm-17/payment-widget ( cb2702...55e70e )
by
unknown
13:32 queued 03:19
created

Jetpack_Tracks_Client::get_anon_id()   D

Complexity

Conditions 10
Paths 4

Size

Total Lines 31
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 15
nc 4
nop 0
dl 0
loc 31
rs 4.8196
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * Jetpack_Tracks_Client
5
 * @autounit nosara tracks-client
6
 *
7
 * Send Tracks events on behalf of a user
8
 *
9
 * Example Usage:
10
```php
11
	require( dirname(__FILE__).'path/to/tracks/class.tracks-client' );
12
13
	$result = Jetpack_Tracks_Client::record_event( array(
14
		'_en'        => $event_name,       // required
15
		'_ui'        => $user_id,          // required unless _ul is provided
16
		'_ul'        => $user_login,       // required unless _ui is provided
17
18
		// Optional, but recommended
19
		'_ts'        => $ts_in_ms,         // Default: now
20
		'_via_ip'    => $client_ip,        // we use it for geo, etc.
21
22
		// Possibly useful to set some context for the event
23
		'_via_ua'    => $client_user_agent,
24
		'_via_url'   => $client_url,
25
		'_via_ref'   => $client_referrer,
26
27
		// For user-targeted tests
28
		'abtest_name'        => $abtest_name,
29
		'abtest_variation'   => $abtest_variation,
30
31
		// Your application-specific properties
32
		'custom_property'    => $some_value,
33
	) );
34
35
	if ( is_wp_error( $result ) ) {
36
		// Handle the error in your app
37
	}
38
```
39
 */
40
41
require_once( dirname(__FILE__).'/class.tracks-client.php' );
42
43
class Jetpack_Tracks_Client {
44
	const PIXEL = 'https://pixel.wp.com/t.gif';
45
	const BROWSER_TYPE = 'php-agent';
46
	const USER_AGENT_SLUG = 'tracks-client';
47
	const VERSION = '0.3';
48
49
	/**
50
	 * record_event
51
	 * @param  mixed  $event Event object to send to Tracks. An array will be cast to object. Required.
52
	 *                       Properties are included directly in the pixel query string after light validation.
53
	 * @return mixed         True on success, WP_Error on failure
54
	 */
55
	static function record_event( $event ) {
56
		if ( ! $event instanceof Jetpack_Tracks_Event ) {
57
			$event = new Jetpack_Tracks_Event( $event );
58
		}
59
		if ( is_wp_error( $event ) ) {
60
			return $event;
61
		}
62
63
		$pixel = $event->build_pixel_url( $event );
0 ignored issues
show
Unused Code introduced by
The call to Jetpack_Tracks_Event::build_pixel_url() has too many arguments starting with $event.

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...
64
65
		if ( ! $pixel ) {
66
			return new WP_Error( 'invalid_pixel', 'cannot generate tracks pixel for given input', 400 );
67
		}
68
69
		return self::record_pixel( $pixel );
70
	}
71
72
	/**
73
	 * Synchronously request the pixel
74
	 */
75
	static function record_pixel( $pixel ) {
76
		// Add the Request Timestamp and URL terminator just before the HTTP request.
77
		$pixel .= '&_rt=' . self::build_timestamp() . '&_=_';
78
79
		$response = wp_remote_get( $pixel, array(
80
			'blocking'    => true, // The default, but being explicit here :)
81
			'timeout'     => 1,
82
			'redirection' => 2,
83
			'httpversion' => '1.1',
84
			'user-agent'  => self::get_user_agent(),
85
		) );
86
87
		if ( is_wp_error( $response ) ) {
88
			return $response;
89
		}
90
91
		$code = isset( $response['response']['code'] ) ? $response['response']['code'] : 0;
92
93
		if ( $code !== 200 ) {
94
			return new WP_Error( 'request_failed', 'Tracks pixel request failed', $code );
95
		}
96
97
		return true;
98
	}
99
100
	static function get_user_agent() {
101
		return Jetpack_Tracks_Client::USER_AGENT_SLUG . '-v' . Jetpack_Tracks_Client::VERSION;
102
	}
103
104
	/**
105
	 * Build an event and return its tracking URL
106
	 * @deprecated          Call the `build_pixel_url` method on a Jetpack_Tracks_Event object instead.
107
	 * @param  array $event Event keys and values
108
	 * @return string       URL of a tracking pixel
109
	 */
110
	static function build_pixel_url( $event ) {
111
		$_event = new Jetpack_Tracks_Event( $event );
112
		return $_event->build_pixel_url();
113
	}
114
115
	/**
116
	 * Validate input for a tracks event.
117
	 * @deprecated          Instantiate a Jetpack_Tracks_Event object instead
118
	 * @param  array $event Event keys and values
119
	 * @return mixed        Validated keys and values or WP_Error on failure
120
	 */
121
	private static function validate_and_sanitize( $event ) {
122
		$_event = new Jetpack_Tracks_Event( $event );
123
		if ( is_wp_error( $_event ) ) {
124
			return $_event;
125
		}
126
		return get_object_vars( $_event );
127
	}
128
129
	// Milliseconds since 1970-01-01
130
	static function build_timestamp() {
131
		$ts = round( microtime( true ) * 1000 );
132
		return number_format( $ts, 0, '', '' );
133
	}
134
135
	/**
136
	 * Grabs the user's anon id from cookies, or generates and sets a new one
137
	 *
138
	 * @return string An anon id for the user
139
	 */
140
	static function get_anon_id() {
141
		static $anon_id = null;
142
143
		if ( ! isset( $anon_id ) ) {
144
145
			// Did the browser send us a cookie?
146
			if ( isset( $_COOKIE[ 'tk_ai' ] ) && preg_match( '#^[A-Za-z0-9+/=]{24}$#', $_COOKIE[ 'tk_ai' ] ) ) {
147
				$anon_id = $_COOKIE[ 'tk_ai' ];
148
			} else {
149
150
				$binary = '';
151
152
				// Generate a new anonId and try to save it in the browser's cookies
153
				// Note that base64-encoding an 18 character string generates a 24-character anon id
154
				for ( $i = 0; $i < 18; ++$i ) {
155
					$binary .= chr( mt_rand( 0, 255 ) );
156
				}
157
158
				$anon_id = 'jetpack:' . base64_encode( $binary );
159
160
				if ( ! headers_sent()
161
					&& ! ( defined( 'REST_REQUEST' ) && REST_REQUEST )
162
					&& ! ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST )
163
				) {
164
					setcookie( 'tk_ai', $anon_id );
165
				}
166
			}
167
		}
168
169
		return $anon_id;
170
	}
171
172
	/**
173
	 * Gets the WordPress.com user's Tracks identity, if connected.
174
	 *
175
	 * @return array|bool
176
	 */
177
	static function get_connected_user_tracks_identity() {
178
		if ( ! $user_data = Jetpack::get_connected_user_data() ) {
179
			return false;
180
		}
181
182
		return array(
183
			'userid' => $user_data['ID'],
184
			'username' => $user_data['login'],
185
		);
186
	}
187
}
188