Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
33 / 33
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
User_Account_Status
100.00% covered (success)
100.00%
33 / 33
100.00% covered (success)
100.00%
3 / 3
12
100.00% covered (success)
100.00%
1 / 1
 check_account_errors
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
2
 possible_account_mismatch
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
4
 clean_account_mismatch_transients
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
6
1<?php
2/**
3 * Class to check for account errors in the Jetpack Connection.
4 *
5 * @package automattic/jetpack-connection
6 * @since 6.11.0
7 */
8
9namespace Automattic\Jetpack\Connection;
10
11/**
12 * Class User_Account_Status
13 */
14class User_Account_Status {
15    /**
16     * Check for possible account errors between the local user and WPCOM account.
17     *
18     * @since 6.11.0
19     *
20     * @param string $current_user_email The email of the current WordPress user.
21     * @param string $wpcom_user_email The email of the connected WordPress.com account.
22     *
23     * @return array An array of possible account errors, empty if no errors.
24     */
25    public function check_account_errors( $current_user_email, $wpcom_user_email ) {
26        $errors = array();
27
28        // Check for email mismatch error.
29        $has_mismatch = $this->possible_account_mismatch( $current_user_email, $wpcom_user_email );
30        if ( $has_mismatch ) {
31            $errors['mismatch'] = array(
32                'type'    => 'mismatch',
33                'message' => __( 'Your WordPress.com email is also used by another user account. This won’t affect functionality but may cause confusion about which user account is connected.', 'jetpack-connection' ),
34                'details' => array(
35                    'site_email'  => $current_user_email,
36                    'wpcom_email' => $wpcom_user_email,
37                ),
38            );
39        }
40
41        /**
42         * Filters the account errors.
43         *
44         * @since 6.11.0
45         *
46         * @param array  $errors             The array of account errors.
47         * @param string $current_user_email The email of the current WordPress user.
48         * @param string $wpcom_user_email   The email of the connected WordPress.com account.
49         */
50        return apply_filters( 'jetpack_connection_account_errors', $errors, $current_user_email, $wpcom_user_email );
51    }
52
53    /**
54     * Check if there is a possible account mismatch between the local user and WPCOM account.
55     *
56     * @since 6.11.0
57     *
58     * @param string $current_user_email The email of the current WordPress user.
59     * @param string $wpcom_user_email The email of the connected WordPress.com account.
60     *
61     * @return bool Whether there is a possible account mismatch.
62     */
63    public function possible_account_mismatch( $current_user_email, $wpcom_user_email ) {
64        // If emails are the same or there's no WPCOM email, there's no mismatch.
65        if ( $current_user_email === $wpcom_user_email || ! $wpcom_user_email ) {
66            return false;
67        }
68
69        // Generate transient key with both wpcom email and user ID if available.
70        $transient_key  = 'jetpack_account_mismatch_';
71        $transient_key .= md5( $wpcom_user_email );
72
73        $cached_result = get_transient( $transient_key );
74
75        if ( false !== $cached_result ) {
76            return (bool) $cached_result;
77        }
78
79        // Check if there's a WordPress user with the WPCOM email .
80        $wpcom_email_user = get_user_by( 'email', $wpcom_user_email );
81        $mismatch_exists  = false !== $wpcom_email_user;
82
83        // Store the result in a transient for 24 hours.
84        set_transient( $transient_key, $mismatch_exists, DAY_IN_SECONDS );
85
86        return $mismatch_exists;
87    }
88
89    /**
90     * Clears account mismatch transients for a user when they update their email or are deleted.
91     *
92     * @since 6.11.0
93     *
94     * @param string|int $user_id_or_email User ID or email address.
95     * @return void
96     */
97    public function clean_account_mismatch_transients( $user_id_or_email ) {
98        $email = null;
99
100        if ( is_numeric( $user_id_or_email ) ) {
101            $user = get_userdata( $user_id_or_email );
102            if ( $user && isset( $user->user_email ) ) {
103                $email = $user->user_email;
104            }
105        } else {
106            $email = $user_id_or_email;
107        }
108
109        if ( ! $email || ! is_email( $email ) ) {
110            return;
111        }
112
113        $transient_key = 'jetpack_account_mismatch_' . md5( $email );
114        delete_transient( $transient_key );
115    }
116}