Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
75.76% covered (warning)
75.76%
25 / 33
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
WP_Mail
75.76% covered (warning)
75.76%
25 / 33
50.00% covered (danger)
50.00%
1 / 2
19.65
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 add_autologin_links_to_email
74.19% covered (warning)
74.19%
23 / 31
0.00% covered (danger)
0.00%
0 / 1
18.87
1<?php
2/**
3 * Class to filter wp_mail and add autologin codes to urls in the message body.
4 *
5 * @link       https://BrianHenry.ie
6 * @since      1.0.0
7 *
8 * @package    bh-wp-autologin-urls
9 */
10
11namespace BrianHenryIE\WP_Autologin_URLs\WP_Includes;
12
13use BrianHenryIE\WP_Autologin_URLs\API_Interface;
14use BrianHenryIE\WP_Autologin_URLs\Settings_Interface;
15
16/**
17 * The wp_mail hooked functionality of the plugin.
18 */
19class WP_Mail {
20
21    /**
22     * The class which adds the autologin codes to the emails.
23     *
24     * @var API_Interface
25     */
26    protected $api;
27
28    /**
29     * The settings, as configured in the WordPress admin UI.
30     *
31     * @var Settings_Interface
32     */
33    protected $settings;
34
35    /**
36     * WP_Mail constructor.
37     *
38     * @param API_Interface      $api          The API class for adding the autologin code to URLs.
39     * @param Settings_Interface $settings     The settings to be used.
40     */
41    public function __construct( API_Interface $api, Settings_Interface $settings ) {
42
43        $this->api      = $api;
44        $this->settings = $settings;
45    }
46
47    /**
48     * Assumed added as a filter on wp_mail(), this function uses the api class to add
49     * autologin codes to urls in emails, as appropriate with the configured settings.
50     *
51     * @hooked wp_mail
52     *
53     * @param array{to:string|array<string>, subject:string, message:string, headers?:string|array<string>, attachments:string|array<string>} $wp_mail_args The arguments passed to wp_mail() (before processing).
54     *
55     * @return array{to:string|array<string>, subject:string, message:string, headers?:string|array<string>, attachments:string|array<string>}
56     * @see wp_mail()
57     */
58    public function add_autologin_links_to_email( array $wp_mail_args ): array {
59
60        $to = $wp_mail_args['to'];
61
62        if ( is_array( $to ) && count( $to ) !== 1 ) {
63            return $wp_mail_args;
64        }
65
66        if ( is_array( $to ) ) {
67            $to = array_pop( $to );
68        }
69
70        $user = get_user_by( 'email', $wp_mail_args['to'] );
71
72        // If the email recipient does not have a user account on this site, return the message unchanged.
73        if ( ! $user ) {
74            return $wp_mail_args;
75        }
76
77        // If there are no links in the message to this site, return.
78        if ( ! stristr( $wp_mail_args['message'], get_site_url() ) ) {
79            return $wp_mail_args;
80        }
81
82        $should_add_autologin = true;
83
84        // The default setting does not add autologin codes in emails to admins.
85        if ( $user->has_cap( 'administrator' ) && ! $this->settings->get_add_autologin_for_admins_is_enabled() ) {
86            $should_add_autologin = false;
87        }
88
89        /**
90         * To override for all users use:
91         * `add_filter( 'autologin_urls_for_users', '__return_true' );`
92         *
93         * @see https://codex.wordpress.org/Function_Reference/_return_true
94         * @see https://codex.wordpress.org/Function_Reference/_return_false
95         *
96         * @param bool     $should_add_autologin Variable to change to true if the urls should log in admin users.
97         * @param \WP_User  $user The WordPress user the email is being sent to.
98         * @param array    $wp_mail_args The array of values wp_mail() functions uses: subject, message etc.
99         */
100        $should_add_autologin = apply_filters( 'autologin_urls_for_users', $should_add_autologin, $user, $wp_mail_args );
101
102        $disallowed_subjects_regex_array = $this->settings->get_disallowed_subjects_regex_array();
103
104        /**
105         * To add or remove regex filters for message subjects:
106         * `add_filter( 'autologin_urls_disallowed_subject_regexes', 'my_function', 10, 3 )`
107         *
108         * @param array    $disallowed_subjects_regex_array
109         * @param \WP_User  $user The WordPress user the email is being sent to.
110         * @param array    $wp_mail_args The array of values wp_mail() functions uses: subject, message etc.
111         */
112        $disallowed_subjects_regex_array = apply_filters( 'autologin_urls_disallowed_subject_regexes', $disallowed_subjects_regex_array, $user, $wp_mail_args );
113
114        foreach ( $disallowed_subjects_regex_array as $disallowed_subject_regex ) {
115
116            if ( preg_match( $disallowed_subject_regex, $wp_mail_args['subject'] ) ) {
117
118                $should_add_autologin = false;
119
120            }
121        }
122
123        /**
124         * Exclude emails being sent to multiple recipients.
125         */
126        if ( isset( $wp_mail_args['headers'] ) ) {
127
128            $headers = $wp_mail_args['headers'];
129
130            if ( is_string( $headers ) ) {
131                $headers = array( $headers );
132            }
133
134            foreach ( $headers as $header ) {
135                if ( 1 === preg_match( '/^b?cc:/i', $header ) ) {
136                    $should_add_autologin = false;
137                    break;
138                }
139            }
140        }
141
142        if ( ! $should_add_autologin ) {
143
144            return $wp_mail_args;
145        }
146
147        // The heavy lifting.
148        $wp_mail_args['message'] = $this->api->add_autologin_to_message( $wp_mail_args['message'], $user, null );
149
150        return $wp_mail_args;
151    }
152}