1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace LeKoala\Mailgun; |
4
|
|
|
|
5
|
|
|
use Pelago\Emogrifier; |
6
|
|
|
use Pelago\Emogrifier\CssInliner; |
7
|
|
|
use Pelago\Emogrifier\HtmlProcessor\HtmlPruner; |
8
|
|
|
use Pelago\Emogrifier\HtmlProcessor\CssToAttributeConverter; |
9
|
|
|
|
10
|
|
|
class EmailUtils |
11
|
|
|
{ |
12
|
|
|
|
13
|
|
|
/** |
14
|
|
|
* Inline styles using Pelago Emogrifier |
15
|
|
|
* |
16
|
|
|
* This is much better than the functionnality provided by Mailgun anyway |
17
|
|
|
* |
18
|
|
|
* @param string $html |
19
|
|
|
* @return string |
20
|
|
|
*/ |
21
|
|
|
public static function inline_styles($html) |
22
|
|
|
{ |
23
|
|
|
if (class_exists(CssInliner::class)) { |
24
|
|
|
// V3 |
25
|
|
|
$cssInliner = CssInliner::fromHtml($html)->inlineCss(''); |
26
|
|
|
$domDocument = $cssInliner->getDomDocument(); |
27
|
|
|
|
28
|
|
|
// potentially, we could also remove classes |
29
|
|
|
// HtmlPruner::fromDomDocument($domDocument)->removeElementsWithDisplayNone() |
30
|
|
|
// ->removeRedundantClassesAfterCssInlined($cssInliner); |
31
|
|
|
|
32
|
|
|
// disableInvisibleNodeRemoval |
33
|
|
|
HtmlPruner::fromDomDocument($domDocument)->removeElementsWithDisplayNone(); |
34
|
|
|
|
35
|
|
|
// enableCssToHtmlMapping |
36
|
|
|
$html = CssToAttributeConverter::fromDomDocument($domDocument) |
37
|
|
|
->convertCssToVisualAttributes()->render(); |
38
|
|
|
} else { |
39
|
|
|
// V2 |
40
|
|
|
$emogrifier = new Emogrifier(); |
41
|
|
|
$emogrifier->disableInvisibleNodeRemoval(); |
|
|
|
|
42
|
|
|
$emogrifier->enableCssToHtmlMapping(); |
|
|
|
|
43
|
|
|
$emogrifier->setHtml($html); |
44
|
|
|
$html = $emogrifier->emogrify(); |
45
|
|
|
} |
46
|
|
|
|
47
|
|
|
return $html; |
48
|
|
|
} |
49
|
|
|
|
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* Convert an html email to a text email while keeping formatting and links |
53
|
|
|
* |
54
|
|
|
* @param string $content |
55
|
|
|
* @return string |
56
|
|
|
*/ |
57
|
|
|
public static function convert_html_to_text($content) |
58
|
|
|
{ |
59
|
|
|
// Prevent styles to be included |
60
|
|
|
$content = preg_replace('/<style.*>([\s\S]*)<\/style>/i', '', $content); |
61
|
|
|
// Convert html entities to strip them later on |
62
|
|
|
$content = html_entity_decode($content); |
63
|
|
|
// Bold |
64
|
|
|
$content = str_ireplace(['<strong>', '</strong>', '<b>', '</b>'], "*", $content); |
65
|
|
|
// Replace links to keep them accessible |
66
|
|
|
$content = preg_replace('/<a[\s\S]href="(.*?)"[\s\S]*?>(.*?)<\/a>/i', '$2 ($1)', $content); |
67
|
|
|
// Replace new lines |
68
|
|
|
$content = str_replace(['<br>', '<br/>', '<br />'], "\r\n", $content); |
69
|
|
|
// Remove html tags |
70
|
|
|
$content = strip_tags($content); |
71
|
|
|
// Avoid lots of spaces |
72
|
|
|
$content = preg_replace('/^[\s][\s]+(\S)/m', "\n$1", $content); |
73
|
|
|
// Trim content so that it's nice |
74
|
|
|
$content = trim($content); |
75
|
|
|
return $content; |
76
|
|
|
} |
77
|
|
|
|
78
|
|
|
/** |
79
|
|
|
* Match all words and whitespace, will be terminated by '<' |
80
|
|
|
* |
81
|
|
|
* Note: use /u to support utf8 strings |
82
|
|
|
* |
83
|
|
|
* @param string $rfc_email_string |
84
|
|
|
* @return string |
85
|
|
|
*/ |
86
|
|
|
public static function get_displayname_from_rfc_email($rfc_email_string) |
87
|
|
|
{ |
88
|
|
|
$name = preg_match('/[\w\s-\.]+/u', $rfc_email_string, $matches); |
89
|
|
|
$matches[0] = trim($matches[0]); |
90
|
|
|
return $matches[0]; |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
/** |
94
|
|
|
* Extract parts between brackets |
95
|
|
|
* |
96
|
|
|
* @param string $rfc_email_string |
97
|
|
|
* @return string |
98
|
|
|
*/ |
99
|
|
|
public static function get_email_from_rfc_email($rfc_email_string) |
100
|
|
|
{ |
101
|
|
|
if (strpos($rfc_email_string, '<') === false) { |
102
|
|
|
return $rfc_email_string; |
103
|
|
|
} |
104
|
|
|
$mailAddress = preg_match('/(?:<)(.+)(?:>)$/', $rfc_email_string, $matches); |
105
|
|
|
if (empty($matches)) { |
106
|
|
|
return $rfc_email_string; |
107
|
|
|
} |
108
|
|
|
return $matches[1]; |
109
|
|
|
} |
110
|
|
|
} |
111
|
|
|
|
This method has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.