Completed
Push — 19-feature/export-logs-in-batc... ( a346a8...47f618 )
by Sudar
15:28 queued 09:06
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, 'log_email' ) );
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
	 * Logs email to database.
32
	 *
33
	 * @param array $original_mail_info Information about email.
34
	 *
35
	 * @return array Information about email.
36
	 */
37 1
	public function log_email( $original_mail_info ) {
38
		/**
39
		 * Hook to modify wp_mail contents before Email Log plugin logs.
40
		 *
41
		 * @param array $original_mail_info {
42
		 *     @type string|array $to
43
		 *     @type string       $subject
44
		 *     @type string       $message
45
		 *     @type string|array $headers
46
		 *     @type string|array $attachment
47
		 * }
48
		 *
49
		 * @since 2.0.0
50
		 */
51 1
		$original_mail_info = apply_filters( 'el_wp_mail_log', $original_mail_info );
52
53
		// Sometimes the array passed to the `wp_mail` filter may not contain all the required keys.
54
		// See https://wordpress.org/support/topic/illegal-string-offset-attachments/.
55 1
		$mail_info = wp_parse_args(
56 1
			$original_mail_info,
57
			array(
58 1
				'to'          => '',
59
				'subject'     => '',
60
				'message'     => '',
61
				'headers'     => '',
62
				'attachments' => array(),
63
			)
64
		);
65
66
		$log = array(
67 1
			'to_email'        => \EmailLog\Util\stringify( $mail_info['to'] ),
68 1
			'subject'         => $mail_info['subject'],
69 1
			'message'         => $mail_info['message'],
70 1
			'headers'         => \EmailLog\Util\stringify( $mail_info['headers'], "\n" ),
71 1
			'attachment_name' => \EmailLog\Util\stringify( $mail_info['attachments'] ),
72 1
			'sent_date'       => current_time( 'mysql' ),
73 1
			'ip_address'      => $_SERVER['REMOTE_ADDR'],
74 1
			'result'          => 1,
75
		);
76
77 1
		if ( empty( $log['attachment_name'] ) ) {
78 1
			$log['attachments'] = 'false';
79
		} else {
80
			$log['attachments'] = 'true';
81
		}
82
83
		/**
84
		 * Filters the mail info right before inserting on the table.
85
		 *
86
		 * Masked fields would use this filter to avoid modifying the original data sent to
87
		 * `wp_mail() function`
88
		 *
89
		 * @param array $log                Email Log that is about to be inserted into db.
90
		 * @param array $original_mail_info Original mail info that was passed to `wp_mail` filter.
91
		 *
92
		 * @since 2.3.2
93
		 */
94 1
		$log = apply_filters( 'el_email_log_before_insert', $log, $original_mail_info );
95
96 1
		$email_log = email_log();
97 1
		$email_log->table_manager->insert_log( $log );
98
99
		/**
100
		 * Fires the `el_email_log_inserted` action right after the log is inserted in to DB.
101
		 *
102
		 * @since 2.3.0
103
		 *
104
		 * @param array $log {
105
		 *      @type string $to
106
		 *      @type string $subject
107
		 *      @type string $message
108
		 *      @type string $headers
109
		 *      @type string $attachments
110
		 *      @type string $attachment_name
111
		 *      @type string $sent_date
112
		 *      @type string $ip_address
113
		 *      @type bool   $result
114
		 * }
115
		 */
116 1
		do_action( 'el_email_log_inserted', $log );
117
118 1
		return $original_mail_info;
119
	}
120
121
	/**
122
	 * Updates the failed email in the DB.
123
	 *
124
	 * @param \WP_Error $wp_error The error instance.
125
	 *
126
	 * @since 2.4.0 Use is_wp_error() to validate the type of $wp_error.
127
	 * @since 2.3.0
128
	 *
129
	 * @see   is_wp_error()
130
	 * @see   email_log()
131
	 */
132
	public function on_email_failed( $wp_error ) {
133
		if ( ! is_wp_error( $wp_error ) ) {
134
			return;
135
		}
136
137
		// @see wp-includes/pluggable.php#500
138
		$mail_error_data = $wp_error->get_error_data( 'wp_mail_failed' );
139
		$mail_error_message = $wp_error->get_error_message( 'wp_mail_failed' );
140
141
		$this->mark_email_log_as_failed( $mail_error_data, $mail_error_message );
142
	}
143
144
	/**
145
	 * Prepare BuddyPress emails to log into database.
146
	 *
147
	 * @since 2.3.2
148
	 *
149
	 * @param bool      $status  Mail sent status.
150
	 * @param \BP_Email $bp_mail Information about email.
151
	 */
152
	public function log_buddy_press_email( $status, $bp_mail ) {
153
		if ( ! class_exists( '\\BP_Email' ) ) {
154
			return;
155
		}
156
157
		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...
158
			return;
159
		}
160
161
		$log = array(
162
			'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

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