Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 70 |
|
0.00% |
0 / 4 |
CRAP | |
0.00% |
0 / 1 |
EchoHtmlEmailFormatter | |
0.00% |
0 / 70 |
|
0.00% |
0 / 4 |
72 | |
0.00% |
0 / 1 |
formatModel | |
0.00% |
0 / 26 |
|
0.00% |
0 / 1 |
20 | |||
renderBody | |
0.00% |
0 / 19 |
|
0.00% |
0 / 1 |
2 | |||
getFooter | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
6 | |||
renderLink | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\Notifications\Formatters; |
4 | |
5 | use Language; |
6 | use MediaWiki\Html\Html; |
7 | use MediaWiki\Parser\Sanitizer; |
8 | use MediaWiki\SpecialPage\SpecialPage; |
9 | |
10 | class EchoHtmlEmailFormatter extends EchoEventFormatter { |
11 | |
12 | public const PRIMARY_LINK_STYLE = |
13 | 'cursor: pointer;' . |
14 | 'text-align: center;' . |
15 | 'text-decoration: none;' . |
16 | 'padding: 6px 10px;' . |
17 | 'border-radius: 2px;' . |
18 | 'color: #FFF;' . |
19 | 'background: #36C;' . |
20 | 'font-family: Arial, Helvetica, sans-serif;' . |
21 | 'font-weight: bold;' . |
22 | 'font-size: 13px;'; |
23 | |
24 | public const SECONDARY_LINK_STYLE = |
25 | 'text-decoration: none;' . |
26 | 'font-size: 10px;' . |
27 | 'font-family: Arial, Helvetica, sans-serif;' . |
28 | 'color: #72777D;'; |
29 | |
30 | protected function formatModel( EchoEventPresentationModel $model ) { |
31 | $subject = $model->getSubjectMessage()->parse(); |
32 | |
33 | $intro = $model->getHeaderMessage()->parse(); |
34 | |
35 | $bodyMsg = $model->getBodyMessage(); |
36 | $summary = $bodyMsg ? $bodyMsg->parse() : ''; |
37 | |
38 | $actions = []; |
39 | |
40 | $primaryLink = $model->getPrimaryLinkWithMarkAsRead(); |
41 | if ( $primaryLink ) { |
42 | $actions[] = $this->renderLink( $primaryLink, self::PRIMARY_LINK_STYLE ); |
43 | } |
44 | |
45 | foreach ( array_filter( $model->getSecondaryLinks() ) as $secondaryLink ) { |
46 | $actions[] = $this->renderLink( $secondaryLink, self::SECONDARY_LINK_STYLE ); |
47 | } |
48 | |
49 | $iconUrl = wfExpandUrl( |
50 | EchoIcon::getRasterizedUrl( $model->getIconType(), $this->language->getCode() ), |
51 | PROTO_CANONICAL |
52 | ); |
53 | |
54 | $body = $this->renderBody( |
55 | $this->language, |
56 | $iconUrl, |
57 | $summary, |
58 | implode( " ", $actions ), |
59 | $intro, |
60 | $this->getFooter() |
61 | ); |
62 | |
63 | return [ |
64 | 'body' => $body, |
65 | 'subject' => $subject, |
66 | ]; |
67 | } |
68 | |
69 | private function renderBody( Language $lang, $emailIcon, $summary, $action, $intro, $footer ) { |
70 | $alignStart = $lang->alignStart(); |
71 | $langCode = $lang->getHtmlCode(); |
72 | $langDir = $lang->getDir(); |
73 | |
74 | $iconImgSrc = Sanitizer::encodeAttribute( $emailIcon ); |
75 | |
76 | global $wgCanonicalServer; |
77 | // phpcs:disable Generic.Files.LineLength |
78 | return <<< EOF |
79 | <html><head> |
80 | <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> |
81 | <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
82 | <style> |
83 | @media only screen and (max-width: 480px){ |
84 | table[id="email-container"]{max-width:600px !important; width:100% !important;} |
85 | } |
86 | </style> |
87 | <base href="{$wgCanonicalServer}"> |
88 | </head><body> |
89 | <table cellspacing="0" cellpadding="0" border="0" width="100%" align="center" lang="{$langCode}" dir="{$langDir}"> |
90 | <tr> |
91 | <td bgcolor="#EAECF0"><center> |
92 | <br /><br /> |
93 | <table cellspacing="0" cellpadding="0" border="0" width="600" id="email-container"> |
94 | <tr> |
95 | <td bgcolor="#FFFFFF" width="5%"> </td> |
96 | <td bgcolor="#FFFFFF" width="10%"> </td> |
97 | <td bgcolor="#FFFFFF" width="80%" style="line-height:40px;"> </td> |
98 | <td bgcolor="#FFFFFF" width="5%"> </td> |
99 | </tr><tr> |
100 | <td bgcolor="#FFFFFF" rowspan="2"> </td> |
101 | <td bgcolor="#FFFFFF" align="center" valign="top" rowspan="2"><img src="{$iconImgSrc}" alt="" height="30" width="30"></td> |
102 | <td bgcolor="#FFFFFF" align="{$alignStart}" style="font-family: Arial, Helvetica, sans-serif; font-size:13px; line-height:20px; color:#72777D;">{$intro}</td> |
103 | <td bgcolor="#FFFFFF" rowspan="2"> </td> |
104 | </tr><tr> |
105 | <td bgcolor="#FFFFFF" align="{$alignStart}" style="font-family: Arial, Helvetica, sans-serif; line-height: 20px; font-weight: 600;"> |
106 | <table cellspacing="0" cellpadding="0" border="0"> |
107 | <tr> |
108 | <td bgcolor="#FFFFFF" align="{$alignStart}" style="font-family: Arial, Helvetica, sans-serif; padding-top: 8px; font-size:13px; font-weight: bold; color: #54595D;"> |
109 | {$summary} |
110 | </td> |
111 | </tr> |
112 | </table> |
113 | <table cellspacing="0" cellpadding="0" border="0"> |
114 | <tr> |
115 | <td bgcolor="#FFFFFF" align="{$alignStart}" style="font-family: Arial, Helvetica, sans-serif; font-size:14px; padding-top: 25px;"> |
116 | {$action} |
117 | </td> |
118 | </tr> |
119 | </table> |
120 | </td> |
121 | </tr><tr> |
122 | <td bgcolor="#FFFFFF"> </td> |
123 | <td bgcolor="#FFFFFF"> </td> |
124 | <td bgcolor="#FFFFFF" style="line-height:40px;"> </td> |
125 | <td bgcolor="#FFFFFF"> </td> |
126 | </tr><tr> |
127 | <td> </td> |
128 | <td> </td> |
129 | <td align="{$alignStart}" style="font-family: Arial, Helvetica, sans-serif; font-size:10px; line-height:13px; color:#72777D; padding:10px 20px;"><br /> |
130 | {$footer} |
131 | <br /><br /> |
132 | </td> |
133 | <td> </td> |
134 | </tr><tr> |
135 | <td colspan="4"> </td> |
136 | </tr> |
137 | </table> |
138 | <br><br></center> |
139 | </td> |
140 | </tr> |
141 | </table> |
142 | </body></html> |
143 | EOF; |
144 | // phpcs:enable Generic.Files.LineLength |
145 | } |
146 | |
147 | /** |
148 | * @return string |
149 | */ |
150 | public function getFooter() { |
151 | global $wgEchoEmailFooterAddress; |
152 | |
153 | $preferenceLink = $this->renderLink( |
154 | [ |
155 | 'label' => $this->msg( 'echo-email-html-footer-preference-link-text', $this->user ) |
156 | ->text(), |
157 | 'url' => SpecialPage::getTitleFor( 'Preferences', false, 'mw-prefsection-echo' ) |
158 | ->getFullURL( '', false, PROTO_CANONICAL ), |
159 | ], |
160 | 'text-decoration: none; color: #36C;' |
161 | ); |
162 | |
163 | $footer = $this->msg( 'echo-email-html-footer-with-link' ) |
164 | ->rawParams( $preferenceLink ) |
165 | ->params( $this->user ) |
166 | ->parse(); |
167 | |
168 | if ( $wgEchoEmailFooterAddress ) { |
169 | $footer .= '<br />' . $wgEchoEmailFooterAddress; |
170 | } |
171 | |
172 | return $footer; |
173 | } |
174 | |
175 | private function renderLink( $link, $style ) { |
176 | return Html::element( |
177 | 'a', |
178 | [ |
179 | 'href' => wfExpandUrl( $link['url'], PROTO_CANONICAL ), |
180 | 'style' => $style, |
181 | ], |
182 | $link['label'] |
183 | ); |
184 | } |
185 | } |