Passed
Pull Request — dev/2.3.2 (#251)
by Sudar
03:30
created

EmailLogger::log_bp_emails()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 7
c 1
b 0
f 0
nc 2
nop 2
dl 0
loc 9
ccs 1
cts 1
cp 1
crap 2
rs 10
1
<?php namespace EmailLog\Core;
2
3
/**
4
 * Log's emails sent through `wp_mail`.
5
 *
6
 * @package EmailLog\Core
7
 * @since   2.0
8
 */
9
class EmailLogger implements Loadie {
10
11
	/**
12
	 * Load the logger.
13
	 */
14
	public function load() {
15
		add_filter( 'wp_mail', array( $this, 'log_email' ) );
16
		add_action( 'wp_mail_failed', array( $this, 'update_email_fail_status' ) );
17
		/**
18
		 * These actions are required for logging buddy press emails as buddy press does
19
		 * not use wp_mail for sending emails.
20
		 */
21
		add_action( 'bp_send_email_success', array( $this, 'log_bp_emails' ), 10, 2 );
22
		add_action( 'bp_send_email_failure', array( $this, 'log_bp_emails' ), 10, 2 );
23
	}
24
25
	/**
26 1
	 * Preparae buddy press emails to log into database.
27
	 *
28
	 * @param bool  $status       Mail sent status.
29
	 * @param array $bp_mail_info Information about email
30
	 *
31
	 * @return void
32
	 */
33
    public function log_bp_emails( $status, $bp_mail_info ) {
34
        $bp_for_email_log = array(
35
            'to'          => array_shift( $bp_mail_info->get_to() )->get_address(),
0 ignored issues
show
Bug introduced by
$bp_mail_info->get_to() cannot be passed to array_shift() as the parameter $array expects a reference. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

35
            'to'          => array_shift( /** @scrutinizer ignore-type */ $bp_mail_info->get_to() )->get_address(),
Loading history...
36
            'subject'     => $bp_mail_info->get( 'subject' ),
37
            'message'     => $bp_mail_info->get_content_plaintext( 'replace-tokens' ),
38
            'headers'     => $bp_mail_info->get_headers(),
39
        );
40 1
		$this->log_email( $bp_for_email_log );
41
		if ( ! $status ) {
42
			// TODO set status to failure.
43
		}
44 1
    }
45 1
46
	/**
47 1
	 * Logs email to database.
48 1
	 *
49 1
	 * @param array $original_mail_info Information about email.
50 1
	 *
51 1
	 * @return array Information about email.
52
	 */
53 1
	public function log_email( $original_mail_info ) {
54
		/**
55
		 * Hook to modify wp_mail contents before Email Log plugin logs.
56 1
		 *
57 1
		 * @param array $original_mail_info {
58 1
		 *     @type string|array $to
59 1
		 *     @type string       $subject
60 1
		 *     @type string       $message
61 1
		 *     @type string|array $headers
62 1
		 *     @type string|array $attachment
63 1
		 * }
64 1
		 *
65
		 * @since 2.0.0
66 1
		 */
67 1
		$original_mail_info = apply_filters( 'el_wp_mail_log', $original_mail_info );
68 1
69
		// Sometimes the array passed to the `wp_mail` filter may not contain all the required keys.
70
		// See https://wordpress.org/support/topic/illegal-string-offset-attachments/.
71
		$mail_info = wp_parse_args(
72
			$original_mail_info,
73
			array(
74
				'to'          => '',
75
				'subject'     => '',
76
				'message'     => '',
77
				'headers'     => '',
78
				'attachments' => array(),
79
			)
80
		);
81
82
		$log = array(
83 1
			'to_email'        => \EmailLog\Util\stringify( $mail_info['to'] ),
84
			'subject'         => $mail_info['subject'],
85 1
			'message'         => $mail_info['message'],
86 1
			'headers'         => \EmailLog\Util\stringify( $mail_info['headers'], "\n" ),
87
			'attachment_name' => \EmailLog\Util\stringify( $mail_info['attachments'] ),
88
			'sent_date'       => current_time( 'mysql' ),
89
			'ip_address'      => $_SERVER['REMOTE_ADDR'],
90
			'result'          => 1,
91
		);
92
93
		if ( empty( $log['attachment_name'] ) ) {
94
			$log['attachments'] = 'false';
95
		} else {
96
			$log['attachments'] = 'true';
97
		}
98
99
		/**
100
		 * Filters the mail info right before inserting on the table.
101
		 *
102
		 * Masked fields would use this filter to avoid modifying the original data sent to
103
		 * `wp_mail() function`
104
		 *
105 1
		 * @param array $log                Email Log that is about to be inserted into db.
106
		 * @param array $original_mail_info Original mail info that was passed to `wp_mail` filter.
107 1
		 *
108
		 * @since 2.3.2
109
		 */
110
		$log = apply_filters( 'el_email_log_before_insert', $log, $original_mail_info );
111
112
		$email_log = email_log();
113
		$email_log->table_manager->insert_log( $log );
114
115
		/**
116
		 * Fires the `el_email_log_inserted` action right after the log is inserted in to DB.
117
		 *
118
		 * @since 2.3.0
119
		 *
120
		 * @param array $log {
121
		 *      @type string $to
122
		 *      @type string $subject
123
		 *      @type string $message
124
		 *      @type string $headers
125
		 *      @type string $attachments
126
		 *      @type string $attachment_name
127
		 *      @type string $sent_date
128
		 *      @type string $ip_address
129
		 *      @type bool   $result
130
		 * }
131
		 */
132
		do_action( 'el_email_log_inserted', $log );
133
134
		return $original_mail_info;
135
	}
136
137
	/**
138
	 * Updates the failed email in the DB.
139
	 *
140
	 * @since 2.3.0
141
	 *
142
	 * @param \WP_Error $wp_error The error instance.
143
	 */
144
	public function update_email_fail_status( $wp_error ) {
145
		if ( ! ( $wp_error instanceof \WP_Error ) ) {
0 ignored issues
show
introduced by
$wp_error is always a sub-type of WP_Error.
Loading history...
146
			return;
147
		}
148
149
		$email_log       = email_log();
150
		$mail_error_data = $wp_error->get_error_data( 'wp_mail_failed' );
151
152
		// $mail_error_data can be of type mixed.
153
		if ( ! is_array( $mail_error_data ) ) {
154
			return;
155
		}
156
157
		// @see wp-includes/pluggable.php#484
158
		$log_item_id = $email_log->table_manager->fetch_log_item_by_item_data( $mail_error_data );
159
		// Empty will handle 0 and return FALSE.
160
		if ( empty( $log_item_id ) ) {
161
			return;
162
		}
163
164
		$email_log->table_manager->set_log_item_fail_status_by_id( $log_item_id );
165
	}
166
}
167