Completed
Branch dev/2.3.2 (ecbaea)
by Sudar
09:33
created

EmailLogger   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 142
Duplicated Lines 0 %

Test Coverage

Coverage 60.38%

Importance

Changes 9
Bugs 0 Features 0
Metric Value
eloc 49
dl 0
loc 142
ccs 32
cts 53
cp 0.6038
rs 10
c 9
b 0
f 0
wmc 12

3 Methods

Rating   Name   Duplication   Size   Complexity  
A load() 0 3 1
A update_email_fail_status() 0 21 4
B log_email() 0 95 7
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
19
	/**
20
	 * Logs email to database.
21
	 *
22
	 * @param array $mail_info Information about email.
23
	 *
24
	 * @return array Information about email.
25
	 */
26 1
	public function log_email( $mail_info ) {
27 1
		$email_log = email_log();
28
		/**
29
		 * Hook to modify wp_mail contents before Email Log plugin logs.
30
		 *
31
		 * @since Genesis
32
		 *
33
		 * @param array $mail_info {
34
		 *     @type string|array $to
35
		 *     @type string       $subject
36
		 *     @type string       $message
37
		 *     @type string       $headers
38
		 *     @type string       $attachment
39
		 *     @type string|array $headers
40
		 *     @type string|array $attachment
41
		 * }
42
		 */
43 1
		$mail_info = apply_filters( 'el_wp_mail_log', $mail_info );
44
45
		// Sometimes the array passed to the `wp_mail` filter may not contain all the required keys.
46
		// See https://wordpress.org/support/topic/illegal-string-offset-attachments/.
47 1
		$cleaned_mail_info = wp_parse_args(
48 1
			$mail_info,
49
			array(
50 1
				'attachments' => array(),
51 1
				'to'          => '',
52 1
				'subject'     => '',
53 1
				'headers'     => '',
54
			)
55 1
		);
56
57
		// ! empty() check on attachments handles both empty string and empty array.
58
		$data = array(
59 1
			'attachments'     => ( ! empty( $cleaned_mail_info['attachments'] ) ) ? 'true' : 'false',
60 1
			'subject'         => $cleaned_mail_info['subject'],
61 1
			'headers'         => is_array( $cleaned_mail_info['headers'] ) ? implode( "\n", $cleaned_mail_info['headers'] ) : $cleaned_mail_info['headers'],
62 1
			'sent_date'       => current_time( 'mysql' ),
63 1
			'attachment_name' => implode( ',', $cleaned_mail_info['attachments'] ),
64
			// TODO: Improve the Client's IP using https://www.virendrachandak.com/techtalk/getting-real-client-ip-address-in-php-2/.
65 1
			'ip_address'      => $_SERVER['REMOTE_ADDR'],
66 1
			'result'          => 1,
67 1
		);
68
69 1
		$to = '';
70 1
		if ( empty( $cleaned_mail_info['to'] ) ) {
71
			$to = '';
72 1
		} elseif ( is_array( $cleaned_mail_info['to'] ) ) {
73 1
			$to = implode( ',', $cleaned_mail_info['to'] );
74 1
		} else {
75
			$to = $cleaned_mail_info['to'];
76
		}
77
78 1
		$data['to_email'] = $to;
79
80 1
		$message = '';
81
82 1
		if ( isset( $cleaned_mail_info['message'] ) ) {
83
			$message = $cleaned_mail_info['message'];
84
		} else {
85
			// wpmandrill plugin is changing "message" key to "html". See https://github.com/sudar/email-log/issues/20
86
			// Ideally this should be fixed in wpmandrill, but I am including this hack here till it is fixed by them.
87 1
			if ( isset( $cleaned_mail_info['html'] ) ) {
88
				$message = $cleaned_mail_info['html'];
89
			}
90
		}
91
92 1
		$data['message'] = $message;
93
94
		/**
95
		 * Filters the mail info right before inserting on the table.
96
		 *
97
		 * Masked fields would use this filter to avoid modifying the original data sent to
98
		 * `wp_mail() function`
99
		 *
100
		 * @since 2.3.2
101
		 */
102 1
		$data = apply_filters( 'el_email_log_before_insert', $data );
103
104 1
		$email_log->table_manager->insert_log( $data );
105
106
		/**
107
		 * Fires the `el_email_log_inserted` action right after the log is inserted in to DB.
108
		 *
109
		 * @param array $data {
110
		 *      @type string $to
111
		 *      @type string $subject
112
		 *      @type string $message
113
		 *      @type string $headers
114
		 *      @type string $attachments
115
		 *      @type string $sent_date
116
		 * }
117
		 */
118 1
		do_action( 'el_email_log_inserted', $data );
119
120 1
		return $mail_info;
121
	}
122
123
	/**
124
	 * Updates the failed email in the DB.
125
	 *
126
	 * @since 2.3.0
127
	 *
128
	 * @param \WP_Error $wp_error The error instance.
129
	 */
130
	public function update_email_fail_status( $wp_error ) {
131
		if ( ! ( $wp_error instanceof \WP_Error ) ) {
0 ignored issues
show
introduced by
$wp_error is always a sub-type of WP_Error.
Loading history...
132
			return;
133
		}
134
135
		$email_log       = email_log();
136
		$mail_error_data = $wp_error->get_error_data( 'wp_mail_failed' );
137
138
		// $mail_error_data can be of type mixed.
139
		if ( ! is_array( $mail_error_data ) ) {
140
			return;
141
		}
142
143
		// @see wp-includes/pluggable.php#484
144
		$log_item_id = $email_log->table_manager->fetch_log_item_by_item_data( $mail_error_data );
145
		// Empty will handle 0 and return FALSE.
146
		if ( empty( $log_item_id ) ) {
147
			return;
148
		}
149
150
		$email_log->table_manager->set_log_item_fail_status_by_id( $log_item_id );
151
	}
152
}
153