27 private function __construct()
45 public static function split(
string $header,
string $separators): array
47 $quotedSeparators = preg_quote($separators,
'/');
54 "(?:[^"\\\\]|\\\\.)*(?:"|\\\\|$)
57 [^"'.$quotedSeparators.
']+
63 (?<separator>['.$quotedSeparators.
'])
65 /x', trim($header), $matches, PREG_SET_ORDER);
67 return self::groupParts($matches, $separators);
83 public static function combine(array $parts): array
86 foreach ($parts as $part) {
87 $name = strtolower($part[0]);
88 $value = $part[1] ??
true;
89 $assoc[$name] = $value;
107 public static function toString(array $assoc,
string $separator): string
110 foreach ($assoc as $name => $value) {
111 if (
true === $value) {
118 return implode($separator.
' ', $parts);
128 public static function quote(
string $s): string
130 if (preg_match(
'/^[a-z0-9!#$%&\'*.^_`|~-]+$/i', $s)) {
134 return '"'.addcslashes($s,
'"\\"').
'"';
143 public static function unquote(
string $s): string
145 return preg_replace(
'/\\\\(.)|"/',
'$1', $s);
163 public static function makeDisposition(
string $disposition,
string $filename,
string $filenameFallback =
''): string
165 if (!\in_array($disposition, [self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE])) {
166 throw new \InvalidArgumentException(sprintf(
'The disposition must be either "%s" or "%s".', self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE));
169 if (
'' === $filenameFallback) {
170 $filenameFallback = $filename;
174 if (!preg_match(
'/^[\x20-\x7e]*$/', $filenameFallback)) {
175 throw new \InvalidArgumentException(
'The filename fallback must only contain ASCII characters.');
179 if (
false !== strpos($filenameFallback,
'%')) {
180 throw new \InvalidArgumentException(
'The filename fallback cannot contain the "%" character.');
184 if (
false !== strpos($filename,
'/') ||
false !== strpos($filename,
'\\') ||
false !== strpos($filenameFallback,
'/') ||
false !== strpos($filenameFallback,
'\\')) {
185 throw new \InvalidArgumentException(
'The filename and the fallback cannot contain the "/" and "\\" characters.');
188 $params = [
'filename' => $filenameFallback];
189 if ($filename !== $filenameFallback) {
190 $params[
'filename*'] =
"utf-8''".rawurlencode($filename);
196 private static function groupParts(array $matches,
string $separators): array
198 $separator = $separators[0];
199 $partSeparators = substr($separators, 1);
203 foreach ($matches as $match) {
204 if (isset($match[
'separator']) && $match[
'separator'] === $separator) {
207 $partMatches[$i][] = $match;
212 if ($partSeparators) {
213 foreach ($partMatches as $matches) {
214 $parts[] = self::groupParts($matches, $partSeparators);
217 foreach ($partMatches as $matches) {