Passed
Pull Request — dev/2.5.0 (#307)
by
unknown
07:19 queued 04:01
created

EmailLogger::log_email()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 82
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 2.0004

Importance

Changes 13
Bugs 0 Features 0
Metric Value
cc 2
eloc 27
c 13
b 0
f 0
nc 2
nop 1
dl 0
loc 82
ccs 20
cts 21
cp 0.9524
crap 2.0004
rs 9.488

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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, 'wp_mail_filter' ) );
16
		add_action( 'wp_mail_failed', array( $this, 'on_email_failed' ) );
17
18
		/**
19
		 * These actions are required for logging BuddyPress emails, since BuddyPress does
20
		 * not use wp_mail for sending emails.
21
		 *
22
		 * Support for BuddyPress was added in v2.3.2
23
		 *
24
		 * @link https://github.com/sudar/email-log/issues/249
25
		 */
26
		add_action( 'bp_send_email_success', array( $this, 'log_buddy_press_email' ), 10, 2 );
27
		add_action( 'bp_send_email_failure', array( $this, 'log_buddy_press_email' ), 10, 2 );
28
	}
29
30
	/**
31
	 * wp_mail filter that logs email to database.
32
	 *
33
	 * @param array $original_mail_info Information about email.
34
	 *
35
	 * @return array Information about email.
36
	 */
37
	public function wp_mail_filter( $original_mail_info ) {
38
		$this->log_email( $original_mail_info );
39
		return $original_mail_info;
40
	}
41
42
	/**
43
	 * Logs email to database.
44
	 *
45
	 * @param array $original_mail_info Information about email.
46
	 *
47
	 * @return boolean|int Insertion failure/success.
48
	 */
49 1
	public function log_email( $original_mail_info ) {
50
		/**
51
		 * Hook to modify wp_mail contents before Email Log plugin logs.
52
		 *
53
		 * @param array $original_mail_info {
54
		 *     @type string|array $to
55
		 *     @type string       $subject
56
		 *     @type string       $message
57
		 *     @type string|array $headers
58
		 *     @type string|array $attachment
59
		 * }
60
		 *
61
		 * @since 2.0.0
62
		 */
63 1
		$original_mail_info = apply_filters( 'el_wp_mail_log', $original_mail_info );
64
65
		// Sometimes the array passed to the `wp_mail` filter may not contain all the required keys.
66
		// See https://wordpress.org/support/topic/illegal-string-offset-attachments/.
67 1
		$mail_info = wp_parse_args(
68 1
			$original_mail_info,
69
			array(
70 1
				'to'          => '',
71
				'subject'     => '',
72
				'message'     => '',
73
				'headers'     => '',
74
				'attachments' => array(),
75
			)
76
		);
77
78
		$log = array(
79 1
			'to_email'        => \EmailLog\Util\stringify( $mail_info['to'] ),
80 1
			'subject'         => $mail_info['subject'],
81 1
			'message'         => $mail_info['message'],
82 1
			'headers'         => \EmailLog\Util\stringify( $mail_info['headers'], "\n" ),
83 1
			'attachment_name' => \EmailLog\Util\stringify( $mail_info['attachments'] ),
84 1
			'sent_date'       => current_time( 'mysql' ),
85 1
			'ip_address'      => $_SERVER['REMOTE_ADDR'],
86 1
			'result'          => 1,
87
		);
88
89 1
		if ( empty( $log['attachment_name'] ) ) {
90 1
			$log['attachments'] = 'false';
91
		} else {
92
			$log['attachments'] = 'true';
93
		}
94
95
		/**
96
		 * Filters the mail info right before inserting on the table.
97
		 *
98
		 * Masked fields would use this filter to avoid modifying the original data sent to
99
		 * `wp_mail() function`
100
		 *
101
		 * @param array $log                Email Log that is about to be inserted into db.
102
		 * @param array $original_mail_info Original mail info that was passed to `wp_mail` filter.
103
		 *
104
		 * @since 2.3.2
105
		 */
106 1
		$log = apply_filters( 'el_email_log_before_insert', $log, $original_mail_info );
107
108 1
		$email_log = email_log();
109 1
		$result    = $email_log->table_manager->insert_log( $log );
110
111
		/**
112
		 * Fires the `el_email_log_inserted` action right after the log is inserted in to DB.
113
		 *
114
		 * @since 2.3.0
115
		 *
116
		 * @param array $log {
117
		 *      @type string $to
118
		 *      @type string $subject
119
		 *      @type string $message
120
		 *      @type string $headers
121
		 *      @type string $attachments
122
		 *      @type string $attachment_name
123
		 *      @type string $sent_date
124
		 *      @type string $ip_address
125
		 *      @type bool   $result
126
		 * }
127
		 */
128 1
		do_action( 'el_email_log_inserted', $log );
129
130 1
		return $result;
131
	}
132
133
	/**
134
	 * Updates the failed email in the DB.
135
	 *
136
	 * @param \WP_Error $wp_error The error instance.
137
	 *
138
	 * @since 2.4.0 Use is_wp_error() to validate the type of $wp_error.
139
	 * @since 2.3.0
140
	 *
141
	 * @see   is_wp_error()
142
	 * @see   email_log()
143
	 */
144
	public function on_email_failed( $wp_error ) {
145
		if ( ! is_wp_error( $wp_error ) ) {
146
			return;
147
		}
148
149
		// @see wp-includes/pluggable.php#500
150
		$mail_error_data = $wp_error->get_error_data( 'wp_mail_failed' );
151
		$mail_error_message = $wp_error->get_error_message( 'wp_mail_failed' );
152
153
		$this->mark_email_log_as_failed( $mail_error_data, $mail_error_message );
154
	}
155
156
	/**
157
	 * Prepare BuddyPress emails to log into database.
158
	 *
159
	 * @since 2.3.2
160
	 *
161
	 * @param bool      $status  Mail sent status.
162
	 * @param \BP_Email $bp_mail Information about email.
163
	 */
164
	public function log_buddy_press_email( $status, $bp_mail ) {
165
		if ( ! class_exists( '\\BP_Email' ) ) {
166
			return;
167
		}
168
169
		if ( $bp_mail instanceof \BP_Email ) {
0 ignored issues
show
Bug introduced by
The type BP_Email was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
170
			return;
171
		}
172
173
		$log = array(
174
			'to'      => array_shift( $bp_mail->get_to() )->get_address(),
0 ignored issues
show
Bug introduced by
$bp_mail->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

174
			'to'      => array_shift( /** @scrutinizer ignore-type */ $bp_mail->get_to() )->get_address(),
Loading history...
175
			'subject' => $bp_mail->get_subject( 'replace-tokens' ),
176
			'message' => $bp_mail->get_content( 'replace-tokens' ),
177
			'headers' => $bp_mail->get_headers( 'replace-tokens ' ),
178
		);
179
180
		$this->log_email( $log );
181
182
		if ( ! $status ) {
183
			$this->mark_email_log_as_failed( $log );
184
		}
185
	}
186
187
	/**
188
	 * Mark email log as failed.
189
	 *
190
	 * @param array  $log           Email Log.
191
	 * @param string $error_message Error message.
192
	 *
193
	 * @since 2.3.2
194
	 * @since 2.4.0 Store the error message.
195
	 */
196
	protected function mark_email_log_as_failed( $log, $error_message = '' ) {
197
		if ( ! is_array( $log ) ) {
0 ignored issues
show
introduced by
The condition is_array($log) is always true.
Loading history...
198
			return;
199
		}
200
201
		if ( ! isset( $log['to'], $log['subject'] ) ) {
202
			return;
203
		}
204
205
		$email_log = email_log();
206
207
		$log_item_id = $email_log->table_manager->fetch_log_id_by_data( $log );
208
209
		if ( empty( $log_item_id ) ) {
210
			return;
211
		}
212
213
		$email_log->table_manager->mark_log_as_failed( $log_item_id, $error_message );
214
	}
215
}
216