[TASK] Update php-cs-fixer to 2.5.0
[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 }
39 if ($name) {
40 return [$address => $name];
41 }
42 return [$address];
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 }
57 return null;
58 }
59
60 /**
61 * Creates a valid email address for the sender of mail messages.
62 *
63 * Uses a fallback chain:
64 * $TYPO3_CONF_VARS['MAIL']['defaultMailFromAddress'] ->
65 * no-reply@FirstDomainRecordFound ->
66 * no-reply@php_uname('n') ->
67 * no-reply@example.com
68 *
69 * Ready to be passed to $mail->setFrom()
70 *
71 * @return string An email address
72 */
73 public static function getSystemFromAddress()
74 {
75 // default, first check the localconf setting
76 $address = $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromAddress'];
77 if (!GeneralUtility::validEmail($address)) {
78 // just get us a domain record we can use as the host
79 $host = '';
80 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
81 ->getQueryBuilderForTable('sys_domain');
82
83 $queryBuilder->getRestrictions()
84 ->removeAll()
85 ->add(GeneralUtility::makeInstance(HiddenRestriction::class));
86
87 $domainRecord = $queryBuilder
88 ->select('domainName')
89 ->from('sys_domain')
90 ->orderBy('pid', 'ASC')
91 ->orderBy('sorting', 'ASC')
92 ->execute()
93 ->fetch();
94
95 if (!empty($domainRecord['domainName'])) {
96 $tempUrl = $domainRecord['domainName'];
97 if (!GeneralUtility::isFirstPartOfStr($tempUrl, 'http')) {
98 // shouldn't be the case anyways, but you never know
99 // ... there're crazy people out there
100 $tempUrl = 'http://' . $tempUrl;
101 }
102 $host = parse_url($tempUrl, PHP_URL_HOST);
103 }
104 $address = 'no-reply@' . $host;
105 if (!GeneralUtility::validEmail($address)) {
106 // still nothing, get host name from server
107 $address = 'no-reply@' . php_uname('n');
108 if (!GeneralUtility::validEmail($address)) {
109 // if everything fails use a dummy address
110 $address = 'no-reply@example.com';
111 }
112 }
113 }
114 return $address;
115 }
116
117 /**
118 * Breaks up a single line of text for emails
119 * Words - longer than $lineWidth - will not be split into parts
120 *
121 * @param string $str The string to break up
122 * @param string $newlineChar The string to implode the broken lines with (default/typically \n)
123 * @param int $lineWidth The line width
124 * @return string Reformated text
125 */
126 public static function breakLinesForEmail($str, $newlineChar = LF, $lineWidth = 76)
127 {
128 $lines = [];
129 $substrStart = 0;
130 while (strlen($str) > $substrStart) {
131 $substr = substr($str, $substrStart, $lineWidth);
132 // has line exceeded (reached) the maximum width?
133 if (strlen($substr) == $lineWidth) {
134 // find last space-char
135 $spacePos = strrpos(rtrim($substr), ' ');
136 // space-char found?
137 if ($spacePos !== false) {
138 // take everything up to last space-char
139 $theLine = substr($substr, 0, $spacePos);
140 $substrStart++;
141 } else {
142 // search for space-char in remaining text
143 // makes this line longer than $lineWidth!
144 $afterParts = explode(' ', substr($str, $lineWidth + $substrStart), 2);
145 $theLine = $substr . $afterParts[0];
146 }
147 if ($theLine === '') {
148 // prevent endless loop because of empty line
149 break;
150 }
151 } else {
152 $theLine = $substr;
153 }
154 $lines[] = trim($theLine);
155 $substrStart += strlen($theLine);
156 if (trim(substr($str, $substrStart, $lineWidth)) === '') {
157 // no more text
158 break;
159 }
160 }
161 return implode($newlineChar, $lines);
162 }
163
164 /**
165 * Parses mailbox headers and turns them into an array.
166 *
167 * Mailbox headers are a comma separated list of 'name <email@example.org>' combinations
168 * or plain email addresses (or a mix of these).
169 * The resulting array has key-value pairs where the key is either a number
170 * (no display name in the mailbox header) and the value is the email address,
171 * or the key is the email address and the value is the display name.
172 *
173 * @param string $rawAddresses Comma separated list of email addresses (optionally with display name)
174 * @return array Parsed list of addresses.
175 */
176 public static function parseAddresses($rawAddresses)
177 {
178 /** @var $addressParser \TYPO3\CMS\Core\Mail\Rfc822AddressesParser */
179 $addressParser = GeneralUtility::makeInstance(
180 \TYPO3\CMS\Core\Mail\Rfc822AddressesParser::class,
181 $rawAddresses
182 );
183 $addresses = $addressParser->parseAddressList();
184 $addressList = [];
185 foreach ($addresses as $address) {
186 if ($address->mailbox === '') {
187 continue;
188 }
189 if ($address->personal) {
190 // item with name found ( name <email@example.org> )
191 $addressList[$address->mailbox . '@' . $address->host] = $address->personal;
192 } else {
193 // item without name found ( email@example.org )
194 $addressList[] = $address->mailbox . '@' . $address->host;
195 }
196 }
197 return $addressList;
198 }
199 }