Test Failed
Push — master ( 73b77e...92d1bc )
by Paul
04:01
created

Email::compose()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 10
ccs 9
cts 9
cp 1
crap 1
rs 9.9332
c 0
b 0
f 0
1
<?php
2
3
namespace GeminiLabs\SiteReviews\Modules;
4
5
use GeminiLabs\SiteReviews\Database\OptionManager;
6
use GeminiLabs\SiteReviews\Defaults\EmailDefaults;
7
use GeminiLabs\SiteReviews\Modules\Html\Template;
8
use PHPMailer;
9
10
class Email
11
{
12
	/**
13
	 * @var array
14
	 */
15
	public $attachments;
16
17
	/**
18
	 * @var array
19
	 */
20
	public $email;
21
22
	/**
23
	 * @var array
24
	 */
25
	public $headers;
26
27
	/**
28
	 * @var string
29
	 */
30
	public $message;
31
32
	/**
33
	 * @var string
34
	 */
35
	public $subject;
36
37
	/**
38
	 * @var string
39
	 */
40
	public $to;
41
42
	/**
43
	 * @return Email
44
	 */
45
	public function compose( array $email )
46
	{
47
		$this->normalize( $email );
48
		$this->attachments = $this->email['attachments'];
49
		$this->headers = $this->buildHeaders();
50
		$this->message = $this->buildHtmlMessage();
51
		$this->subject = $this->email['subject'];
52
		$this->to = $this->email['to'];
53
		add_action( 'phpmailer_init', [$this, 'buildPlainTextMessage'] );
54
		return $this;
55
	}
56
57
	/**
58
	 * @param string $format
59
	 * @return string|null
60
	 */
61
	public function read( $format = '' )
62
	{
63
		if( $format == 'plaintext' )) {
0 ignored issues
show
Bug introduced by
A parse error occurred: Syntax error, unexpected ')' on line 63 at column 30
Loading history...
64
			$message = $this->stripHtmlTags( $this->message );
65
			return apply_filters( 'site-reviews/email/message', $message, 'text', $this );
66
		}
67
		return $this->message;
68
	}
69
70
	/**
71
	 * @return void|bool
72
	 */
73
	public function send()
74
	{
75
		if( !$this->message || !$this->subject || !$this->to )return;
76
		$sent = wp_mail(
77
			$this->to,
78
			$this->subject,
79
			$this->message,
80
			$this->headers,
81
			$this->attachments
82
		);
83
		$this->reset();
84
		return $sent;
85
	}
86
87
	/**
88
	 * @return void
89
	 * @action phpmailer_init
90
	 */
91
	public function buildPlainTextMessage( PHPMailer $phpmailer )
92
	{
93
		if( empty( $this->email ))return;
94
		if( $phpmailer->ContentType === 'text/plain' || !empty( $phpmailer->AltBody ))return;
95
		$message = $this->stripHtmlTags( $phpmailer->Body );
96
		$phpmailer->AltBody = apply_filters( 'site-reviews/email/message', $message, 'text', $this );
97
	}
98
99
	/**
100
	 * @return array
101
	 */
102
	protected function buildHeaders()
103
	{
104
		$allowed = [
105
			'bcc', 'cc', 'from', 'reply-to',
106
		];
107
		$headers = array_intersect_key( $this->email, array_flip( $allowed ));
108
		$headers = array_filter( $headers );
109
		foreach( $headers as $key => $value ) {
110
			unset( $headers[$key] );
111
			$headers[] = $key.': '.$value;
112
		}
113
		$headers[] = 'Content-Type: text/html';
114
		return apply_filters( 'site-reviews/email/headers', $headers, $this );
115
	}
116
117
	/**
118
	 * @return string
119
	 */
120
	protected function buildHtmlMessage()
121
	{
122
		$template = trim( glsr( OptionManager::class )->get( 'settings.general.notification_message' ));
123
		if( !empty( $template )) {
124
			$message = glsr( Template::class )->interpolate( $template, $this->email['template-tags'] );
125
		}
126
		else if( $this->email['template'] ) {
127
			$message = glsr( Template::class )->build( 'templates/'.$this->email['template'], [
128
				'context' => $this->email['template-tags'],
129
			]);
130
		}
131
		if( !isset( $message )) {
132
			$message = $this->email['message'];
133
		}
134
		$message = $this->email['before'].$message.$this->email['after'];
135
		$message = strip_shortcodes( $message );
136
		$message = wptexturize( $message );
137
		$message = wpautop( $message );
138
		$message = str_replace( '&lt;&gt; ', '', $message );
139
		$message = str_replace( ']]>', ']]&gt;', $message );
140
		$message = glsr( Template::class )->build( 'partials/email/index', [
141
			'context' => ['message' => $message],
142
		]);
143
		return apply_filters( 'site-reviews/email/message', stripslashes( $message ), 'html', $this );
144
	}
145
146
	/**
147
	 * @return void
148
	 */
149
	protected function normalize( array $email = [] )
150
	{
151
		$email = shortcode_atts( glsr( EmailDefaults::class )->defaults(), $email );
152
		if( empty( $email['reply-to'] )) {
153
			$email['reply-to'] = $email['from'];
154
		}
155
		$this->email = apply_filters( 'site-reviews/email/compose', $email, $this );
156
	}
157
158
	/**
159
	 * @return void
160
	 */
161
	protected function reset()
162
	{
163
		$this->attachments = [];
164
		$this->email = [];
165
		$this->headers = [];
166
		$this->message = null;
167
		$this->subject = null;
168
		$this->to = null;
169
	}
170
171
	/**
172
	 * @return string
173
	 */
174
	protected function stripHtmlTags( $string )
175
	{
176
		// remove invisible elements
177
		$string = preg_replace( '@<(embed|head|noembed|noscript|object|script|style)[^>]*?>.*?</\\1>@siu', '', $string );
178
		// replace certain elements with a line-break
179
		$string = preg_replace( '@</(div|h[1-9]|p|pre|tr)@iu', "\r\n\$0", $string );
180
		// replace other elements with a space
181
		$string = preg_replace( '@</(td|th)@iu', " \$0", $string );
182
		// add a placeholder for plain-text bullets to list elements
183
		$string = preg_replace( '@<(li)[^>]*?>@siu', "\$0-o-^-o-", $string );
184
		// strip all remaining HTML tags
185
		$string = wp_strip_all_tags( $string );
186
		$string = wp_specialchars_decode( $string, ENT_QUOTES );
187
		$string = preg_replace( '/\v(?:[\v\h]+){2,}/', "\r\n\r\n", $string );
188
		$string = str_replace( '-o-^-o-', ' - ', $string );
189
		return html_entity_decode( $string, ENT_QUOTES, 'UTF-8' );
190
	}
191
}
192