Passed
Push — master ( 92d1bc...99b252 )
by Paul
04:41
created

Email::buildHtmlMessage()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 4.1755

Importance

Changes 0
Metric Value
cc 4
nc 6
nop 0
dl 0
loc 24
ccs 14
cts 18
cp 0.7778
crap 4.1755
rs 9.536
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 1
	public function compose( array $email )
46
	{
47 1
		$this->normalize( $email );
48 1
		$this->attachments = $this->email['attachments'];
49 1
		$this->headers = $this->buildHeaders();
50 1
		$this->message = $this->buildHtmlMessage();
51 1
		$this->subject = $this->email['subject'];
52 1
		$this->to = $this->email['to'];
53 1
		add_action( 'phpmailer_init', [$this, 'buildPlainTextMessage'] );
54 1
		return $this;
55
	}
56
57
	/**
58
	 * @param string $format
59
	 * @return string|null
60
	 */
61
	public function read( $format = '' )
62
	{
63
		if( $format == 'plaintext' ) {
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 1
	public function send()
74
	{
75 1
		if( !$this->message || !$this->subject || !$this->to )return;
76 1
		$sent = wp_mail(
77 1
			$this->to,
78 1
			$this->subject,
79 1
			$this->message,
80 1
			$this->headers,
81 1
			$this->attachments
82
		);
83 1
		$this->reset();
84 1
		return $sent;
85
	}
86
87
	/**
88
	 * @return void
89
	 * @action phpmailer_init
90
	 */
91 1
	public function buildPlainTextMessage( PHPMailer $phpmailer )
92
	{
93 1
		if( empty( $this->email ))return;
94 1
		if( $phpmailer->ContentType === 'text/plain' || !empty( $phpmailer->AltBody ))return;
95 1
		$message = $this->stripHtmlTags( $phpmailer->Body );
96 1
		$phpmailer->AltBody = apply_filters( 'site-reviews/email/message', $message, 'text', $this );
97 1
	}
98
99
	/**
100
	 * @return array
101
	 */
102 1
	protected function buildHeaders()
103
	{
104
		$allowed = [
105 1
			'bcc', 'cc', 'from', 'reply-to',
106
		];
107 1
		$headers = array_intersect_key( $this->email, array_flip( $allowed ));
108 1
		$headers = array_filter( $headers );
109 1
		foreach( $headers as $key => $value ) {
110 1
			unset( $headers[$key] );
111 1
			$headers[] = $key.': '.$value;
112
		}
113 1
		$headers[] = 'Content-Type: text/html';
114 1
		return apply_filters( 'site-reviews/email/headers', $headers, $this );
115
	}
116
117
	/**
118
	 * @return string
119
	 */
120 1
	protected function buildHtmlMessage()
121
	{
122 1
		$template = trim( glsr( OptionManager::class )->get( 'settings.general.notification_message' ));
123 1
		if( !empty( $template )) {
124 1
			$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 1
		if( !isset( $message )) {
132
			$message = $this->email['message'];
133
		}
134 1
		$message = $this->email['before'].$message.$this->email['after'];
135 1
		$message = strip_shortcodes( $message );
136 1
		$message = wptexturize( $message );
137 1
		$message = wpautop( $message );
138 1
		$message = str_replace( '&lt;&gt; ', '', $message );
139 1
		$message = str_replace( ']]>', ']]&gt;', $message );
140 1
		$message = glsr( Template::class )->build( 'partials/email/index', [
141 1
			'context' => ['message' => $message],
142
		]);
143 1
		return apply_filters( 'site-reviews/email/message', stripslashes( $message ), 'html', $this );
144
	}
145
146
	/**
147
	 * @return void
148
	 */
149 1
	protected function normalize( array $email = [] )
150
	{
151 1
		$email = shortcode_atts( glsr( EmailDefaults::class )->defaults(), $email );
152 1
		if( empty( $email['reply-to'] )) {
153 1
			$email['reply-to'] = $email['from'];
154
		}
155 1
		$this->email = apply_filters( 'site-reviews/email/compose', $email, $this );
156 1
	}
157
158
	/**
159
	 * @return void
160
	 */
161 1
	protected function reset()
162
	{
163 1
		$this->attachments = [];
164 1
		$this->email = [];
165 1
		$this->headers = [];
166 1
		$this->message = null;
167 1
		$this->subject = null;
168 1
		$this->to = null;
169 1
	}
170
171
	/**
172
	 * @return string
173
	 */
174 1
	protected function stripHtmlTags( $string )
175
	{
176
		// remove invisible elements
177 1
		$string = preg_replace( '@<(embed|head|noembed|noscript|object|script|style)[^>]*?>.*?</\\1>@siu', '', $string );
178
		// replace certain elements with a line-break
179 1
		$string = preg_replace( '@</(div|h[1-9]|p|pre|tr)@iu', "\r\n\$0", $string );
180
		// replace other elements with a space
181 1
		$string = preg_replace( '@</(td|th)@iu', " \$0", $string );
182
		// add a placeholder for plain-text bullets to list elements
183 1
		$string = preg_replace( '@<(li)[^>]*?>@siu', "\$0-o-^-o-", $string );
184
		// strip all remaining HTML tags
185 1
		$string = wp_strip_all_tags( $string );
186 1
		$string = wp_specialchars_decode( $string, ENT_QUOTES );
187 1
		$string = preg_replace( '/\v(?:[\v\h]+){2,}/', "\r\n\r\n", $string );
188 1
		$string = str_replace( '-o-^-o-', ' - ', $string );
189 1
		return html_entity_decode( $string, ENT_QUOTES, 'UTF-8' );
190
	}
191
}
192