Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 64
0.00% covered (danger)
0.00%
0 / 11
CRAP
0.00% covered (danger)
0.00%
0 / 1
Tracking
0.00% covered (danger)
0.00%
0 / 64
0.00% covered (danger)
0.00%
0 / 11
342
0.00% covered (danger)
0.00%
0 / 1
 init
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
6
 jetpack_activate_module
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 jetpack_deactivate_module
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 jetpack_user_authorized
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
20
 jetpack_verify_secrets_begin
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 jetpack_verify_secrets_success
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 jetpack_verify_secrets_fail
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
 wp_login_failed
n/a
0 / 0
n/a
0 / 0
1
 jetpack_connection_register_fail
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
 jetpack_connection_register_success
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
 jetpack_xmlrpc_server_event
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
12
 jetpack_verify_api_authorization_request_error_double_encode
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * Tracks class.
4 *
5 * @package automattic/jetpack
6 */
7
8namespace Automattic\Jetpack\Plugin;
9
10use Automattic\Jetpack\Connection\Manager as Connection_Manager;
11use Automattic\Jetpack\Tracking as Tracks;
12use IXR_Error;
13use WP_Error;
14use WP_User;
15
16/**
17 * Tracks class.
18 */
19class Tracking {
20    /**
21     * Tracking object.
22     *
23     * @var Tracks
24     *
25     * @access private
26     */
27    private $tracking;
28
29    /**
30     * Prevents the Tracking from being initialized more than once.
31     *
32     * @var bool
33     */
34    private static $initialized = false;
35
36    /**
37     * Initialization function.
38     */
39    public function init() {
40        if ( static::$initialized ) {
41            return;
42        }
43
44        static::$initialized = true;
45        $this->tracking      = new Tracks( 'jetpack' );
46
47        // For tracking stuff via js/ajax.
48        add_action( 'admin_enqueue_scripts', array( $this->tracking, 'enqueue_tracks_scripts' ) );
49
50        add_action( 'jetpack_activate_module', array( $this, 'jetpack_activate_module' ), 1, 1 );
51        add_action( 'jetpack_deactivate_module', array( $this, 'jetpack_deactivate_module' ), 1, 1 );
52        add_action( 'jetpack_user_authorized', array( $this, 'jetpack_user_authorized' ) );
53
54        // Tracking XMLRPC server events.
55        add_action( 'jetpack_xmlrpc_server_event', array( $this, 'jetpack_xmlrpc_server_event' ), 10, 4 );
56
57        // Track that we've begun verifying the previously generated secret.
58        add_action( 'jetpack_verify_secrets_begin', array( $this, 'jetpack_verify_secrets_begin' ), 10, 2 );
59        add_action( 'jetpack_verify_secrets_success', array( $this, 'jetpack_verify_secrets_success' ), 10, 2 );
60        add_action( 'jetpack_verify_secrets_fail', array( $this, 'jetpack_verify_secrets_fail' ), 10, 3 );
61
62        add_action( 'jetpack_verify_api_authorization_request_error_double_encode', array( $this, 'jetpack_verify_api_authorization_request_error_double_encode' ) );
63        add_action( 'jetpack_connection_register_fail', array( $this, 'jetpack_connection_register_fail' ), 10, 2 );
64        add_action( 'jetpack_connection_register_success', array( $this, 'jetpack_connection_register_success' ) );
65    }
66
67    /**
68     * Track that a specific module has been activated.
69     *
70     * @access public
71     *
72     * @param string $module Module slug.
73     */
74    public function jetpack_activate_module( $module ) {
75        $this->tracking->record_user_event( 'module_activated', array( 'module' => $module ) );
76    }
77
78    /**
79     * Track that a specific module has been deactivated.
80     *
81     * @access public
82     *
83     * @param string $module Module slug.
84     */
85    public function jetpack_deactivate_module( $module ) {
86        $this->tracking->record_user_event( 'module_deactivated', array( 'module' => $module ) );
87    }
88
89    /**
90     * Track that the user has successfully received an auth token.
91     *
92     * @access public
93     */
94    public function jetpack_user_authorized() {
95        $user_id = get_current_user_id();
96        $anon_id = get_user_meta( $user_id, 'jetpack_tracks_anon_id', true );
97
98        if ( $anon_id ) {
99            $this->tracking->record_user_event( '_aliasUser', array( 'anonId' => $anon_id ) );
100            delete_user_meta( $user_id, 'jetpack_tracks_anon_id' );
101            if ( ! headers_sent() ) {
102                setcookie( 'tk_ai', 'expired', time() - 1000, COOKIEPATH, COOKIE_DOMAIN, is_ssl(), false );  // phpcs:ignore Jetpack.Functions.SetCookie -- Want this accessible.
103            }
104        }
105
106        $connection_manager = new Connection_Manager();
107        $wpcom_user_data    = $connection_manager->get_connected_user_data( $user_id );
108        if ( isset( $wpcom_user_data['ID'] ) ) {
109            update_user_meta( $user_id, 'jetpack_tracks_wpcom_id', $wpcom_user_data['ID'] );
110        }
111
112        $this->tracking->record_user_event( 'wpa_user_linked', array() );
113    }
114
115    /**
116     * Track that we've begun verifying the secrets.
117     *
118     * @access public
119     *
120     * @param string  $action Type of secret (one of 'register', 'authorize', 'publicize').
121     * @param WP_User $user The user object.
122     */
123    public function jetpack_verify_secrets_begin( $action, $user ) {
124        $this->tracking->record_user_event( "jpc_verify_{$action}_begin", array(), $user );
125    }
126
127    /**
128     * Track that we've succeeded in verifying the secrets.
129     *
130     * @access public
131     *
132     * @param string  $action Type of secret (one of 'register', 'authorize', 'publicize').
133     * @param WP_User $user The user object.
134     */
135    public function jetpack_verify_secrets_success( $action, $user ) {
136        $this->tracking->record_user_event( "jpc_verify_{$action}_success", array(), $user );
137    }
138
139    /**
140     * Track that we've failed verifying the secrets.
141     *
142     * @access public
143     *
144     * @param string   $action Type of secret (one of 'register', 'authorize', 'publicize').
145     * @param WP_User  $user The user object.
146     * @param WP_Error $error Error object.
147     */
148    public function jetpack_verify_secrets_fail( $action, $user, $error ) {
149        $this->tracking->record_user_event(
150            "jpc_verify_{$action}_fail",
151            array(
152                'error_code'    => $error->get_error_code(),
153                'error_message' => $error->get_error_message(),
154            ),
155            $user
156        );
157    }
158
159    /**
160     * Track a failed login attempt.
161     *
162     * @deprecated 13.9 Method is not longer in use.
163     */
164    public function wp_login_failed() {
165        _deprecated_function( __METHOD__, '13.9' );
166    }
167
168    /**
169     * Track a connection failure at the registration step.
170     *
171     * @access public
172     *
173     * @param string|int $error      The error code.
174     * @param WP_Error   $registered The error object.
175     */
176    public function jetpack_connection_register_fail( $error, $registered ) {
177        $this->tracking->record_user_event(
178            'jpc_register_fail',
179            array(
180                'error_code'    => $error,
181                'error_message' => $registered->get_error_message(),
182            )
183        );
184    }
185
186    /**
187     * Track that the registration step of the connection has been successful.
188     *
189     * @access public
190     *
191     * @param string $from The 'from' GET parameter.
192     */
193    public function jetpack_connection_register_success( $from ) {
194        $this->tracking->record_user_event(
195            'jpc_register_success',
196            array(
197                'from' => $from,
198            )
199        );
200    }
201
202    /**
203     * Handles the jetpack_xmlrpc_server_event action that combines several types of events that
204     * happen during request serving.
205     *
206     * @param String                   $action the action name, i.e., 'remote_authorize'.
207     * @param String                   $stage  the execution stage, can be 'begin', 'success', 'error', etc.
208     * @param array|WP_Error|IXR_Error $parameters (optional) extra parameters to be passed to the tracked action.
209     * @param WP_User                  $user (optional) the acting user.
210     */
211    public function jetpack_xmlrpc_server_event( $action, $stage, $parameters = array(), $user = null ) {
212
213        if ( is_wp_error( $parameters ) ) {
214            $parameters = array(
215                'error_code'    => $parameters->get_error_code(),
216                'error_message' => $parameters->get_error_message(),
217            );
218        } elseif ( is_a( $parameters, IXR_Error::class ) ) {
219            $parameters = array(
220                'error_code'    => $parameters->code,
221                'error_message' => $parameters->message,
222            );
223        }
224
225        $this->tracking->record_user_event( 'jpc_' . $action . '_' . $stage, $parameters, $user );
226    }
227
228    /**
229     * Track that the site is incorrectly double-encoding redirects from http to https.
230     *
231     * @access public
232     */
233    public function jetpack_verify_api_authorization_request_error_double_encode() {
234        $this->tracking->record_user_event( 'error_double_encode' );
235    }
236}