c564d465593a7c63e0c77040a829e679831a31b7
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Utility / MailUtility.php
1 <?php
2 namespace TYPO3\CMS\Core\Utility;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Database\ConnectionPool;
18 use TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction;
19
20 /**
21 * Class to handle mail specific functionality
22 */
23 class MailUtility
24 {
25 /**
26 * Gets a valid "from" for mail messages (email and name).
27 *
28 * Ready to be passed to $mail->setFrom()
29 *
30 * @return array key=Valid email address which can be used as sender, value=Valid name which can be used as a sender. NULL if no address is configured
31 */
32 public static function getSystemFrom()
33 {
34 $address = self::getSystemFromAddress();
35 $name = self::getSystemFromName();
36 if (!$address) {
37 return null;
38 } elseif ($name) {
39 return [$address => $name];
40 } else {
41 return [$address];
42 }
43 }
44
45 /**
46 * Creates a valid "from" name for mail messages.
47 *
48 * As configured in Install Tool.
49 *
50 * @return string The name (unquoted, unformatted). NULL if none is set
51 */
52 public static function getSystemFromName()
53 {
54 if ($GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromName']) {
55 return $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromName'];
56 } else {
57 return null;
58 }
59 }
60
61 /**
62 * Creates a valid email address for the sender of mail messages.
63 *
64 * Uses a fallback chain:
65 * $TYPO3_CONF_VARS['MAIL']['defaultMailFromAddress'] ->
66 * no-reply@FirstDomainRecordFound ->
67 * no-reply@php_uname('n') ->
68 * no-reply@example.com
69 *
70 * Ready to be passed to $mail->setFrom()
71 *
72 * @return string An email address
73 */
74 public static function getSystemFromAddress()
75 {
76 // default, first check the localconf setting
77 $address = $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromAddress'];
78 if (!GeneralUtility::validEmail($address)) {
79 // just get us a domain record we can use as the host
80 $host = '';
81 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
82 ->getQueryBuilderForTable('sys_domain');
83
84 $queryBuilder->getRestrictions()
85 ->removeAll()
86 ->add(GeneralUtility::makeInstance(HiddenRestriction::class));
87
88 $domainRecord = $queryBuilder
89 ->select('domainName')
90 ->from('sys_domain')
91 ->orderBy('pid', 'ASC')
92 ->orderBy('sorting', 'ASC')
93 ->execute()
94 ->fetch();
95
96 if (!empty($domainRecord['domainName'])) {
97 $tempUrl = $domainRecord['domainName'];
98 if (!GeneralUtility::isFirstPartOfStr($tempUrl, 'http')) {
99 // shouldn't be the case anyways, but you never know
100 // ... there're crazy people out there
101 $tempUrl = 'http://' . $tempUrl;
102 }
103 $host = parse_url($tempUrl, PHP_URL_HOST);
104 }
105 $address = 'no-reply@' . $host;
106 if (!GeneralUtility::validEmail($address)) {
107 // still nothing, get host name from server
108 $address = 'no-reply@' . php_uname('n');
109 if (!GeneralUtility::validEmail($address)) {
110 // if everything fails use a dummy address
111 $address = 'no-reply@example.com';
112 }
113 }
114 }
115 return $address;
116 }
117
118 /**
119 * Breaks up a single line of text for emails
120 * Words - longer than $lineWidth - will not be split into parts
121 *
122 * @param string $str The string to break up
123 * @param string $newlineChar The string to implode the broken lines with (default/typically \n)
124 * @param int $lineWidth The line width
125 * @return string Reformated text
126 */
127 public static function breakLinesForEmail($str, $newlineChar = LF, $lineWidth = 76)
128 {
129 $lines = [];
130 $substrStart = 0;
131 while (strlen($str) > $substrStart) {
132 $substr = substr($str, $substrStart, $lineWidth);
133 // has line exceeded (reached) the maximum width?
134 if (strlen($substr) == $lineWidth) {
135 // find last space-char
136 $spacePos = strrpos(rtrim($substr), ' ');
137 // space-char found?
138 if ($spacePos !== false) {
139 // take everything up to last space-char
140 $theLine = substr($substr, 0, $spacePos);
141 $substrStart++;
142 } else {
143 // search for space-char in remaining text
144 // makes this line longer than $lineWidth!
145 $afterParts = explode(' ', substr($str, $lineWidth + $substrStart), 2);
146 $theLine = $substr . $afterParts[0];
147 }
148 if ($theLine === '') {
149 // prevent endless loop because of empty line
150 break;
151 }
152 } else {
153 $theLine = $substr;
154 }
155 $lines[] = trim($theLine);
156 $substrStart += strlen($theLine);
157 if (trim(substr($str, $substrStart, $lineWidth)) === '') {
158 // no more text
159 break;
160 }
161 }
162 return implode($newlineChar, $lines);
163 }
164
165 /**
166 * Parses mailbox headers and turns them into an array.
167 *
168 * Mailbox headers are a comma separated list of 'name <email@example.org>' combinations
169 * or plain email addresses (or a mix of these).
170 * The resulting array has key-value pairs where the key is either a number
171 * (no display name in the mailbox header) and the value is the email address,
172 * or the key is the email address and the value is the display name.
173 *
174 * @param string $rawAddresses Comma separated list of email addresses (optionally with display name)
175 * @return array Parsed list of addresses.
176 */
177 public static function parseAddresses($rawAddresses)
178 {
179 /** @var $addressParser \TYPO3\CMS\Core\Mail\Rfc822AddressesParser */
180 $addressParser = GeneralUtility::makeInstance(
181 \TYPO3\CMS\Core\Mail\Rfc822AddressesParser::class,
182 $rawAddresses
183 );
184 $addresses = $addressParser->parseAddressList();
185 $addressList = [];
186 foreach ($addresses as $address) {
187 if ($address->mailbox === '') {
188 continue;
189 }
190 if ($address->personal) {
191 // item with name found ( name <email@example.org> )
192 $addressList[$address->mailbox . '@' . $address->host] = $address->personal;
193 } else {
194 // item without name found ( email@example.org )
195 $addressList[] = $address->mailbox . '@' . $address->host;
196 }
197 }
198 return $addressList;
199 }
200 }