Completed
Push — master ( 8e884b...bea04d )
by Joas
12:13 queued 11:33
created

EMailTemplate   B

Complexity

Total Complexity 43

Size/Duplication

Total Lines 605
Duplicated Lines 7.27 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
dl 44
loc 605
rs 8.0878
c 0
b 0
f 0
wmc 43
lcom 1
cbo 3

16 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 12 1
A setSubject() 0 3 1
A addHeader() 0 9 2
A addHeading() 13 13 4
A ensureBodyIsOpened() 0 8 2
A addBodyText() 15 15 4
C addBodyListItem() 0 28 7
A ensureBodyListOpened() 0 9 2
A ensureBodyListClosed() 0 8 2
B addBodyButtonGroup() 0 27 4
B addBodyButton() 0 22 4
A ensureBodyIsClosed() 0 10 2
A addFooter() 0 17 3
A renderSubject() 0 3 1
A renderHtml() 8 8 2
A renderText() 8 8 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like EMailTemplate often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use EMailTemplate, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * @copyright 2017, Morris Jobke <[email protected]>
4
 * @copyright 2017, Lukas Reschke <[email protected]>
5
 *
6
 * @author Morris Jobke <[email protected]>
7
 * @author Lukas Reschke <[email protected]>
8
 *
9
 * @license GNU AGPL version 3 or any later version
10
 *
11
 * This program is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU Affero General Public License as
13
 * published by the Free Software Foundation, either version 3 of the
14
 * License, or (at your option) any later version.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU Affero General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU Affero General Public License
22
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23
 *
24
 */
25
26
namespace OC\Mail;
27
28
use OCP\Defaults;
29
use OCP\IL10N;
30
use OCP\IURLGenerator;
31
use OCP\Mail\IEMailTemplate;
32
33
/**
34
 * Class EMailTemplate
35
 *
36
 * addBodyText and addBodyButtonGroup automatically opens the body
37
 * addFooter, renderHtml, renderText automatically closes the body and the HTML if opened
38
 *
39
 * @package OC\Mail
40
 */
41
class EMailTemplate implements IEMailTemplate {
42
	/** @var Defaults */
43
	protected $themingDefaults;
44
	/** @var IURLGenerator */
45
	protected $urlGenerator;
46
	/** @var IL10N */
47
	protected $l10n;
48
	/** @var string */
49
	protected $emailId;
50
	/** @var array */
51
	protected $data;
52
53
	/** @var string */
54
	protected $subject = '';
55
	/** @var string */
56
	protected $htmlBody = '';
57
	/** @var string */
58
	protected $plainBody = '';
59
	/** @var bool indicated if the footer is added */
60
	protected $headerAdded = false;
61
	/** @var bool indicated if the body is already opened */
62
	protected $bodyOpened = false;
63
	/** @var bool indicated if there is a list open in the body */
64
	protected $bodyListOpened = false;
65
	/** @var bool indicated if the footer is added */
66
	protected $footerAdded = false;
67
68
	protected $head = <<<EOF
69
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
70
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en" style="-webkit-font-smoothing:antialiased;background:#f3f3f3!important">
71
<head>
72
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
73
	<meta name="viewport" content="width=device-width">
74
	<title></title>
75
	<style type="text/css">@media only screen{html{min-height:100%;background:#F5F5F5}}@media only screen and (max-width:610px){table.body img{width:auto;height:auto}table.body center{min-width:0!important}table.body .container{width:95%!important}table.body .columns{height:auto!important;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;padding-left:30px!important;padding-right:30px!important}th.small-12{display:inline-block!important;width:100%!important}table.menu{width:100%!important}table.menu td,table.menu th{width:auto!important;display:inline-block!important}table.menu.vertical td,table.menu.vertical th{display:block!important}table.menu[align=center]{width:auto!important}}</style>
76
</head>
77
<body style="-moz-box-sizing:border-box;-ms-text-size-adjust:100%;-webkit-box-sizing:border-box;-webkit-font-smoothing:antialiased;-webkit-text-size-adjust:100%;Margin:0;background:#f3f3f3!important;box-sizing:border-box;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;min-width:100%;padding:0;text-align:left;width:100%!important">
78
	<span class="preheader" style="color:#F5F5F5;display:none!important;font-size:1px;line-height:1px;max-height:0;max-width:0;mso-hide:all!important;opacity:0;overflow:hidden;visibility:hidden">
79
	</span>
80
	<table class="body" style="-webkit-font-smoothing:antialiased;Margin:0;background:#f3f3f3!important;border-collapse:collapse;border-spacing:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;height:100%;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;width:100%">
81
		<tr style="padding:0;text-align:left;vertical-align:top">
82
			<td class="center" align="center" valign="top" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
83
				<center data-parsed="" style="min-width:580px;width:100%">
84
EOF;
85
86
	protected $tail = <<<EOF
87
					</center>
88
				</td>
89
			</tr>
90
		</table>
91
		<!-- prevent Gmail on iOS font size manipulation -->
92
		<div style="display:none;white-space:nowrap;font:15px courier;line-height:0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div>
93
	</body>
94
</html>
95
EOF;
96
97
	protected $header = <<<EOF
98
<table align="center" class="wrapper header float-center" style="Margin:0 auto;background:#8a8a8a;background-color:%s;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%%">
99
	<tr style="padding:0;text-align:left;vertical-align:top">
100
		<td class="wrapper-inner" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:20px;text-align:left;vertical-align:top;word-wrap:break-word">
101
			<table align="center" class="container" style="Margin:0 auto;background:0 0;border-collapse:collapse;border-spacing:0;margin:0 auto;padding:0;text-align:inherit;vertical-align:top;width:580px">
102
				<tbody>
103
				<tr style="padding:0;text-align:left;vertical-align:top">
104
					<td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
105
						<table class="row collapse" style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%%">
106
							<tbody>
107
							<tr style="padding:0;text-align:left;vertical-align:top">
108
								<center data-parsed="" style="min-width:580px;width:100%%">
109
									<img class="logo float-center" src="%s" alt="%s" align="center" style="-ms-interpolation-mode:bicubic;Margin:0 auto;clear:both;display:block;float:none;margin:0 auto;outline:0;text-align:center;text-decoration:none" height="50">
110
								</center>
111
							</tr>
112
							</tbody>
113
						</table>
114
					</td>
115
				</tr>
116
				</tbody>
117
			</table>
118
		</td>
119
	</tr>
120
</table>
121
<table class="spacer float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%%">
122
	<tbody>
123
	<tr style="padding:0;text-align:left;vertical-align:top">
124
		<td height="80px" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:80px;font-weight:400;hyphens:auto;line-height:80px;margin:0;mso-line-height-rule:exactly;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">&#xA0;</td>
125
	</tr>
126
	</tbody>
127
</table>
128
EOF;
129
130
	protected $heading = <<<EOF
131
<table align="center" class="container main-heading float-center" style="Margin:0 auto;background:0 0!important;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:580px">
132
	<tbody>
133
	<tr style="padding:0;text-align:left;vertical-align:top">
134
		<td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
135
			<h1 class="text-center" style="Margin:0;Margin-bottom:10px;color:inherit;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:24px;font-weight:400;line-height:1.3;margin:0;margin-bottom:10px;padding:0;text-align:center;word-wrap:normal">%s</h1>
136
		</td>
137
	</tr>
138
	</tbody>
139
</table>
140
<table class="spacer float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%%">
141
	<tbody>
142
	<tr style="padding:0;text-align:left;vertical-align:top">
143
		<td height="40px" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:40px;font-weight:400;hyphens:auto;line-height:40px;margin:0;mso-line-height-rule:exactly;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">&#xA0;</td>
144
	</tr>
145
	</tbody>
146
</table>
147
EOF;
148
149
	protected $bodyBegin = <<<EOF
150
<table align="center" class="wrapper content float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%">
151
	<tr style="padding:0;text-align:left;vertical-align:top">
152
		<td class="wrapper-inner" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
153
			<table align="center" class="container has-shadow" style="Margin:0 auto;background:#fefefe;border-collapse:collapse;border-spacing:0;box-shadow:0 1px 2px 0 rgba(0,0,0,.2),0 1px 3px 0 rgba(0,0,0,.1);margin:0 auto;padding:0;text-align:inherit;vertical-align:top;width:580px">
154
				<tbody>
155
				<tr style="padding:0;text-align:left;vertical-align:top">
156
					<td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
157
						<table class="spacer" style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
158
							<tbody>
159
							<tr style="padding:0;text-align:left;vertical-align:top">
160
								<td height="60px" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:60px;font-weight:400;hyphens:auto;line-height:60px;margin:0;mso-line-height-rule:exactly;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">&#xA0;</td>
161
							</tr>
162
							</tbody>
163
						</table>
164
EOF;
165
166
	protected $bodyText = <<<EOF
167
<table class="row description" style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%%">
168
	<tbody>
169
	<tr style="padding:0;text-align:left;vertical-align:top">
170
		<th class="small-12 large-12 columns first last" style="Margin:0 auto;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0 auto;padding:0;padding-bottom:30px;padding-left:30px;padding-right:30px;text-align:left;width:550px">
171
			<table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%%">
172
				<tr style="padding:0;text-align:left;vertical-align:top">
173
					<th style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0;text-align:left">
174
						<p class="text-left" style="Margin:0;Margin-bottom:10px;color:#777;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;margin-bottom:10px;padding:0;text-align:left">%s</p>
175
					</th>
176
					<th class="expander" style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0!important;text-align:left;visibility:hidden;width:0"></th>
177
				</tr>
178
			</table>
179
		</th>
180
	</tr>
181
	</tbody>
182
</table>
183
EOF;
184
185
	protected $listBegin = <<<EOF
186
<table class="row description" style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%%">
187
	<tbody>
188
	<tr style="padding:0;text-align:left;vertical-align:top">
189
		<th class="small-12 large-12 columns first last" style="Margin:0 auto;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0 auto;padding:0;padding-bottom:30px;padding-left:30px;padding-right:30px;text-align:left;width:550px">
190
			<table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%%">
191
EOF;
192
193
	protected $listItem = <<<EOF
194
				<tr style="padding:0;text-align:left;vertical-align:top">
195
					<td style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0;text-align:left;width:15px;">
196
						<p class="text-left" style="Margin:0;Margin-bottom:10px;color:#777;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;margin-bottom:10px;padding:0;padding-left:10px;text-align:left">%s</p>
197
					</td>
198
					<td style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0;text-align:left">
199
						<p class="text-left" style="Margin:0;Margin-bottom:10px;color:#555;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;margin-bottom:10px;padding:0;padding-left:10px;text-align:left">%s</p>
200
					</td>
201
					<td class="expander" style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0!important;text-align:left;visibility:hidden;width:0"></td>
202
				</tr>
203
EOF;
204
205
	protected $listEnd = <<<EOF
206
			</table>
207
		</th>
208
	</tr>
209
	</tbody>
210
</table>
211
EOF;
212
213
	protected $buttonGroup = <<<EOF
214
<table class="spacer" style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%%">
215
	<tbody>
216
	<tr style="padding:0;text-align:left;vertical-align:top">
217
		<td height="50px" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:50px;font-weight:400;hyphens:auto;line-height:50px;margin:0;mso-line-height-rule:exactly;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">&#xA0;</td>
218
	</tr>
219
	</tbody>
220
</table>
221
<table align="center" class="row btn-group" style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%%">
222
	<tbody>
223
	<tr style="padding:0;text-align:left;vertical-align:top">
224
		<th class="small-12 large-12 columns first last" style="Margin:0 auto;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0 auto;padding:0;padding-bottom:30px;padding-left:30px;padding-right:30px;text-align:left;width:550px">
225
			<table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%%">
226
				<tr style="padding:0;text-align:left;vertical-align:top">
227
					<th style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0;text-align:left">
228
						<center data-parsed="" style="min-width:490px;width:100%%">
229
							<table class="button btn default primary float-center" style="Margin:0 0 30px 0;border-collapse:collapse;border-spacing:0;display:inline-block;float:none;margin:0 0 30px 0;margin-right:15px;max-height:40px;max-width:200px;padding:0;text-align:center;vertical-align:top;width:auto">
230
								<tr style="padding:0;text-align:left;vertical-align:top">
231
									<td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
232
										<table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%%">
233
											<tr style="padding:0;text-align:left;vertical-align:top">
234
												<td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;background:%s;border:0 solid %s;border-collapse:collapse!important;color:#fefefe;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
235
													<a href="%s" style="Margin:0;border:0 solid %s;border-radius:2px;color:#fefefe;display:inline-block;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:regular;line-height:1.3;margin:0;padding:10px 25px 10px 25px;text-align:left;text-decoration:none">%s</a>
236
												</td>
237
											</tr>
238
										</table>
239
									</td>
240
								</tr>
241
							</table>
242
							<table class="button btn default secondary float-center" style="Margin:0 0 30px 0;border-collapse:collapse;border-spacing:0;display:inline-block;float:none;margin:0 0 30px 0;max-height:40px;max-width:200px;padding:0;text-align:center;vertical-align:top;width:auto">
243
								<tr style="padding:0;text-align:left;vertical-align:top">
244
									<td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
245
										<table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%%">
246
											<tr style="padding:0;text-align:left;vertical-align:top">
247
												<td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;background:#777;border:0 solid #777;border-collapse:collapse!important;color:#fefefe;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
248
													<a href="%s" style="Margin:0;background-color:#fff;border:0 solid #777;border-radius:2px;color:#6C6C6C!important;display:inline-block;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:regular;line-height:1.3;margin:0;outline:1px solid #CBCBCB;padding:10px 25px 10px 25px;text-align:left;text-decoration:none">%s</a>
249
												</td>
250
											</tr>
251
										</table>
252
									</td>
253
								</tr>
254
							</table>
255
						</center>
256
					</th>
257
					<th class="expander" style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0!important;text-align:left;visibility:hidden;width:0"></th>
258
				</tr>
259
			</table>
260
		</th>
261
	</tr>
262
	</tbody>
263
</table>
264
EOF;
265
266
	protected $button = <<<EOF
267
<table class="spacer" style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%%">
268
	<tbody>
269
	<tr style="padding:0;text-align:left;vertical-align:top">
270
		<td height="50px" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:50px;font-weight:400;hyphens:auto;line-height:50px;margin:0;mso-line-height-rule:exactly;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">&#xA0;</td>
271
	</tr>
272
	</tbody>
273
</table>
274
<table align="center" class="row btn-group" style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%%">
275
	<tbody>
276
	<tr style="padding:0;text-align:left;vertical-align:top">
277
		<th class="small-12 large-12 columns first last" style="Margin:0 auto;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0 auto;padding:0;padding-bottom:30px;padding-left:30px;padding-right:30px;text-align:left;width:550px">
278
			<table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%%">
279
				<tr style="padding:0;text-align:left;vertical-align:top">
280
					<th style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0;text-align:left">
281
						<center data-parsed="" style="min-width:490px;width:100%%">
282
							<table class="button btn default primary float-center" style="Margin:0;border-collapse:collapse;border-spacing:0;display:inline-block;float:none;margin:0;max-height:40px;padding:0;text-align:center;vertical-align:top;width:auto">
283
								<tr style="padding:0;text-align:left;vertical-align:top">
284
									<td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
285
										<table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%%">
286
											<tr style="padding:0;text-align:left;vertical-align:top">
287
												<td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;background:%s;border:0 solid %s;border-collapse:collapse!important;color:#fefefe;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
288
													<a href="%s" style="Margin:0;border:0 solid %s;border-radius:2px;color:#fefefe;display:inline-block;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:regular;line-height:1.3;margin:0;padding:10px 25px 10px 25px;text-align:left;text-decoration:none">%s</a>
289
												</td>
290
											</tr>
291
										</table>
292
									</td>
293
								</tr>
294
							</table>
295
						</center>
296
					</th>
297
					<th class="expander" style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0!important;text-align:left;visibility:hidden;width:0"></th>
298
				</tr>
299
			</table>
300
		</th>
301
	</tr>
302
	</tbody>
303
</table>
304
EOF;
305
306
	protected $bodyEnd = <<<EOF
307
308
					</td>
309
				</tr>
310
				</tbody>
311
			</table>
312
		</td>
313
	</tr>
314
</table>
315
EOF;
316
317
	protected $footer = <<<EOF
318
<table class="spacer float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%%">
319
	<tbody>
320
	<tr style="padding:0;text-align:left;vertical-align:top">
321
		<td height="60px" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:60px;font-weight:400;hyphens:auto;line-height:60px;margin:0;mso-line-height-rule:exactly;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">&#xA0;</td>
322
	</tr>
323
	</tbody>
324
</table>
325
<table align="center" class="wrapper footer float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%%">
326
	<tr style="padding:0;text-align:left;vertical-align:top">
327
		<td class="wrapper-inner" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
328
			<center data-parsed="" style="min-width:580px;width:100%%">
329
				<table class="spacer float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%%">
330
					<tbody>
331
					<tr style="padding:0;text-align:left;vertical-align:top">
332
						<td height="15px" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:15px;font-weight:400;hyphens:auto;line-height:15px;margin:0;mso-line-height-rule:exactly;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">&#xA0;</td>
333
					</tr>
334
					</tbody>
335
				</table>
336
				<p class="text-center float-center" align="center" style="Margin:0;Margin-bottom:10px;color:#C8C8C8;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:12px;font-weight:400;line-height:16px;margin:0;margin-bottom:10px;padding:0;text-align:center">%s</p>
337
			</center>
338
		</td>
339
	</tr>
340
</table>
341
EOF;
342
343
	/**
344
	 * @param Defaults $themingDefaults
345
	 * @param IURLGenerator $urlGenerator
346
	 * @param IL10N $l10n
347
	 * @param string $emailId
348
	 * @param array $data
349
	 */
350
	public function __construct(Defaults $themingDefaults,
351
								IURLGenerator $urlGenerator,
352
								IL10N $l10n,
353
								$emailId,
354
								array $data) {
355
		$this->themingDefaults = $themingDefaults;
356
		$this->urlGenerator = $urlGenerator;
357
		$this->l10n = $l10n;
358
		$this->htmlBody .= $this->head;
359
		$this->emailId = $emailId;
360
		$this->data = $data;
361
	}
362
363
	/**
364
	 * Sets the subject of the email
365
	 *
366
	 * @param string $subject
367
	 */
368
	public function setSubject($subject) {
369
		$this->subject = $subject;
370
	}
371
372
	/**
373
	 * Adds a header to the email
374
	 */
375
	public function addHeader() {
376
		if ($this->headerAdded) {
377
			return;
378
		}
379
		$this->headerAdded = true;
380
381
		$logoUrl = $this->urlGenerator->getAbsoluteURL($this->themingDefaults->getLogo(false));
382
		$this->htmlBody .= vsprintf($this->header, [$this->themingDefaults->getColorPrimary(), $logoUrl, $this->themingDefaults->getName()]);
383
	}
384
385
	/**
386
	 * Adds a heading to the email
387
	 *
388
	 * @param string $title
389
	 * @param string|bool $plainTitle Title that is used in the plain text email
390
	 *   if empty the $title is used, if false none will be used
391
	 */
392 View Code Duplication
	public function addHeading($title, $plainTitle = '') {
393
		if ($this->footerAdded) {
394
			return;
395
		}
396
		if ($plainTitle === '') {
397
			$plainTitle = $title;
398
		}
399
400
		$this->htmlBody .= vsprintf($this->heading, [htmlspecialchars($title)]);
401
		if ($plainTitle !== false) {
402
			$this->plainBody .= $plainTitle . PHP_EOL . PHP_EOL;
403
		}
404
	}
405
406
	/**
407
	 * Open the HTML body when it is not already
408
	 */
409
	protected function ensureBodyIsOpened() {
410
		if ($this->bodyOpened) {
411
			return;
412
		}
413
414
		$this->htmlBody .= $this->bodyBegin;
415
		$this->bodyOpened = true;
416
	}
417
418
	/**
419
	 * Adds a paragraph to the body of the email
420
	 *
421
	 * @param string $text
422
	 * @param string|bool $plainText Text that is used in the plain text email
423
	 *   if empty the $text is used, if false none will be used
424
	 */
425 View Code Duplication
	public function addBodyText($text, $plainText = '') {
426
		if ($this->footerAdded) {
427
			return;
428
		}
429
		if ($plainText === '') {
430
			$plainText = $text;
431
		}
432
433
		$this->ensureBodyIsOpened();
434
435
		$this->htmlBody .= vsprintf($this->bodyText, [htmlspecialchars($text)]);
436
		if ($plainText !== false) {
437
			$this->plainBody .= $plainText . PHP_EOL . PHP_EOL;
438
		}
439
	}
440
441
	/**
442
	 * Adds a list item to the body of the email
443
	 *
444
	 * @param string $text
445
	 * @param string $metaInfo
446
	 * @param string $icon Absolute path, must be 16*16 pixels
447
	 * @param string $plainText Text that is used in the plain text email
448
	 *   if empty the $text is used, if false none will be used
449
	 * @param string $plainMetaInfo Meta info that is used in the plain text email
450
	 *   if empty the $metaInfo is used, if false none will be used
451
	 * @since 12.0.0
452
	 */
453
	public function addBodyListItem($text, $metaInfo = '', $icon = '', $plainText = '', $plainMetaInfo = '') {
454
		$this->ensureBodyListOpened();
455
456
		if ($plainText === '') {
457
			$plainText = $text;
458
		}
459
		if ($plainMetaInfo === '') {
460
			$plainMetaInfo = $metaInfo;
461
		}
462
463
		$htmlText = htmlspecialchars($text);
464
		if ($metaInfo) {
465
			$htmlText = '<em style="color:#777;">' . htmlspecialchars($metaInfo) . '</em><br>' . $htmlText;
466
		}
467
		if ($icon !== '') {
468
			$icon = '<img src="' . htmlspecialchars($icon) . '" alt="&bull;">';
469
		} else {
470
			$icon = '&bull;';
471
		}
472
		$this->htmlBody .= vsprintf($this->listItem, [$icon, $htmlText]);
473
		if ($plainText !== false) {
474
			$this->plainBody .= '  * ' . $plainText;
475
			if ($plainMetaInfo !== false) {
476
				$this->plainBody .= ' (' . $plainMetaInfo . ')';
477
			}
478
			$this->plainBody .= PHP_EOL;
479
		}
480
	}
481
482
	protected function ensureBodyListOpened() {
483
		if ($this->bodyListOpened) {
484
			return;
485
		}
486
487
		$this->ensureBodyIsOpened();
488
		$this->bodyListOpened = true;
489
		$this->htmlBody .= $this->listBegin;
490
	}
491
492
	protected function ensureBodyListClosed() {
493
		if (!$this->bodyListOpened) {
494
			return;
495
		}
496
497
		$this->bodyListOpened = false;
498
		$this->htmlBody .= $this->listEnd;
499
	}
500
501
	/**
502
	 * Adds a button group of two buttons to the body of the email
503
	 *
504
	 * @param string $textLeft Text of left button
505
	 * @param string $urlLeft URL of left button
506
	 * @param string $textRight Text of right button
507
	 * @param string $urlRight URL of right button
508
	 * @param string $plainTextLeft Text of left button that is used in the plain text version - if unset the $textLeft is used
509
	 * @param string $plainTextRight Text of right button that is used in the plain text version - if unset the $textRight is used
510
	 */
511
	public function addBodyButtonGroup($textLeft,
512
									   $urlLeft,
513
									   $textRight,
514
									   $urlRight,
515
									   $plainTextLeft = '',
516
									   $plainTextRight = '') {
517
		if ($this->footerAdded) {
518
			return;
519
		}
520
		if ($plainTextLeft === '') {
521
			$plainTextLeft = $textLeft;
522
		}
523
524
		if ($plainTextRight === '') {
525
			$plainTextRight = $textRight;
526
		}
527
528
		$this->ensureBodyIsOpened();
529
		$this->ensureBodyListClosed();
530
531
		$color = $this->themingDefaults->getColorPrimary();
532
533
		$this->htmlBody .= vsprintf($this->buttonGroup, [$color, $color, $urlLeft, $color, htmlspecialchars($textLeft), $urlRight, htmlspecialchars($textRight)]);
534
		$this->plainBody .= $plainTextLeft . ': ' . $urlLeft . PHP_EOL;
535
		$this->plainBody .= $plainTextRight . ': ' . $urlRight . PHP_EOL . PHP_EOL;
536
537
	}
538
539
	/**
540
	 * Adds a button to the body of the email
541
	 *
542
	 * @param string $text Text of button
543
	 * @param string $url URL of button
544
	 * @param string $plainText Text of button in plain text version
545
	 * 		if empty the $text is used, if false none will be used
546
	 *
547
	 * @since 12.0.0
548
	 */
549
	public function addBodyButton($text, $url, $plainText = '') {
550
		if ($this->footerAdded) {
551
			return;
552
		}
553
554
		$this->ensureBodyIsOpened();
555
		$this->ensureBodyListClosed();
556
557
		if ($plainText === '') {
558
			$plainText = $text;
559
		}
560
561
		$color = $this->themingDefaults->getColorPrimary();
562
		$this->htmlBody .= vsprintf($this->button, [$color, $color, $url, $color, htmlspecialchars($text)]);
563
564
		if ($plainText !== false) {
565
			$this->plainBody .= $plainText . ': ';
566
		}
567
568
		$this->plainBody .=  $url . PHP_EOL;
569
570
	}
571
572
	/**
573
	 * Close the HTML body when it is open
574
	 */
575
	protected function ensureBodyIsClosed() {
576
		if (!$this->bodyOpened) {
577
			return;
578
		}
579
580
		$this->ensureBodyListClosed();
581
582
		$this->htmlBody .= $this->bodyEnd;
583
		$this->bodyOpened = false;
584
	}
585
586
	/**
587
	 * Adds a logo and a text to the footer. <br> in the text will be replaced by new lines in the plain text email
588
	 *
589
	 * @param string $text If the text is empty the default "Name - Slogan<br>This is an automatically sent email" will be used
590
	 */
591
	public function addFooter($text = '') {
592
		if($text === '') {
593
			$text = $this->themingDefaults->getName() . ' - ' . $this->themingDefaults->getSlogan() . '<br>' . $this->l10n->t('This is an automatically sent email, please do not reply.');
594
		}
595
596
		if ($this->footerAdded) {
597
			return;
598
		}
599
		$this->footerAdded = true;
600
601
		$this->ensureBodyIsClosed();
602
603
		$this->htmlBody .= vsprintf($this->footer, [$text]);
604
		$this->htmlBody .= $this->tail;
605
		$this->plainBody .= PHP_EOL . '-- ' . PHP_EOL;
606
		$this->plainBody .= str_replace('<br>', PHP_EOL, $text);
607
	}
608
609
	/**
610
	 * Returns the rendered email subject as string
611
	 *
612
	 * @return string
613
	 */
614
	public function renderSubject() {
615
		return $this->subject;
616
	}
617
618
	/**
619
	 * Returns the rendered HTML email as string
620
	 *
621
	 * @return string
622
	 */
623 View Code Duplication
	public function renderHtml() {
624
		if (!$this->footerAdded) {
625
			$this->footerAdded = true;
626
			$this->ensureBodyIsClosed();
627
			$this->htmlBody .= $this->tail;
628
		}
629
		return $this->htmlBody;
630
	}
631
632
	/**
633
	 * Returns the rendered plain text email as string
634
	 *
635
	 * @return string
636
	 */
637 View Code Duplication
	public function renderText() {
638
		if (!$this->footerAdded) {
639
			$this->footerAdded = true;
640
			$this->ensureBodyIsClosed();
641
			$this->htmlBody .= $this->tail;
642
		}
643
		return $this->plainBody;
644
	}
645
}
646