Open Journal Systems  3.3.0
HeaderUtils.php
1 <?php
2 
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11 
13 
20 {
21  public const DISPOSITION_ATTACHMENT = 'attachment';
22  public const DISPOSITION_INLINE = 'inline';
23 
27  private function __construct()
28  {
29  }
30 
45  public static function split(string $header, string $separators): array
46  {
47  $quotedSeparators = preg_quote($separators, '/');
48 
49  preg_match_all('
50  /
51  (?!\s)
52  (?:
53  # quoted-string
54  "(?:[^"\\\\]|\\\\.)*(?:"|\\\\|$)
55  |
56  # token
57  [^"'.$quotedSeparators.']+
58  )+
59  (?<!\s)
60  |
61  # separator
62  \s*
63  (?<separator>['.$quotedSeparators.'])
64  \s*
65  /x', trim($header), $matches, PREG_SET_ORDER);
66 
67  return self::groupParts($matches, $separators);
68  }
69 
83  public static function combine(array $parts): array
84  {
85  $assoc = [];
86  foreach ($parts as $part) {
87  $name = strtolower($part[0]);
88  $value = $part[1] ?? true;
89  $assoc[$name] = $value;
90  }
91 
92  return $assoc;
93  }
94 
107  public static function toString(array $assoc, string $separator): string
108  {
109  $parts = [];
110  foreach ($assoc as $name => $value) {
111  if (true === $value) {
112  $parts[] = $name;
113  } else {
114  $parts[] = $name.'='.self::quote($value);
115  }
116  }
117 
118  return implode($separator.' ', $parts);
119  }
120 
128  public static function quote(string $s): string
129  {
130  if (preg_match('/^[a-z0-9!#$%&\'*.^_`|~-]+$/i', $s)) {
131  return $s;
132  }
133 
134  return '"'.addcslashes($s, '"\\"').'"';
135  }
136 
143  public static function unquote(string $s): string
144  {
145  return preg_replace('/\\\\(.)|"/', '$1', $s);
146  }
147 
163  public static function makeDisposition(string $disposition, string $filename, string $filenameFallback = ''): string
164  {
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));
167  }
168 
169  if ('' === $filenameFallback) {
170  $filenameFallback = $filename;
171  }
172 
173  // filenameFallback is not ASCII.
174  if (!preg_match('/^[\x20-\x7e]*$/', $filenameFallback)) {
175  throw new \InvalidArgumentException('The filename fallback must only contain ASCII characters.');
176  }
177 
178  // percent characters aren't safe in fallback.
179  if (false !== strpos($filenameFallback, '%')) {
180  throw new \InvalidArgumentException('The filename fallback cannot contain the "%" character.');
181  }
182 
183  // path separators aren't allowed in either.
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.');
186  }
187 
188  $params = ['filename' => $filenameFallback];
189  if ($filename !== $filenameFallback) {
190  $params['filename*'] = "utf-8''".rawurlencode($filename);
191  }
192 
193  return $disposition.'; '.self::toString($params, ';');
194  }
195 
196  private static function groupParts(array $matches, string $separators): array
197  {
198  $separator = $separators[0];
199  $partSeparators = substr($separators, 1);
200 
201  $i = 0;
202  $partMatches = [];
203  foreach ($matches as $match) {
204  if (isset($match['separator']) && $match['separator'] === $separator) {
205  ++$i;
206  } else {
207  $partMatches[$i][] = $match;
208  }
209  }
210 
211  $parts = [];
212  if ($partSeparators) {
213  foreach ($partMatches as $matches) {
214  $parts[] = self::groupParts($matches, $partSeparators);
215  }
216  } else {
217  foreach ($partMatches as $matches) {
218  $parts[] = self::unquote($matches[0][0]);
219  }
220  }
221 
222  return $parts;
223  }
224 }
Symfony\Component\HttpFoundation\HeaderUtils\toString
static toString(array $assoc, string $separator)
Definition: HeaderUtils.php:107
Symfony\Component\HttpFoundation\HeaderUtils\DISPOSITION_ATTACHMENT
const DISPOSITION_ATTACHMENT
Definition: HeaderUtils.php:21
Symfony\Component\HttpFoundation\HeaderUtils\combine
static combine(array $parts)
Definition: HeaderUtils.php:83
Symfony\Component\HttpFoundation\HeaderUtils\DISPOSITION_INLINE
const DISPOSITION_INLINE
Definition: HeaderUtils.php:22
Symfony\Component\HttpFoundation\HeaderUtils
Definition: HeaderUtils.php:19
Symfony\Component\HttpFoundation
Definition: lib/vendor/symfony/http-foundation/AcceptHeader.php:12
Symfony\Component\HttpFoundation\HeaderUtils\split
static split(string $header, string $separators)
Definition: HeaderUtils.php:45
Symfony\Component\HttpFoundation\HeaderUtils\quote
static quote(string $s)
Definition: HeaderUtils.php:128
Symfony\Component\HttpFoundation\HeaderUtils\unquote
static unquote(string $s)
Definition: HeaderUtils.php:143
Symfony\Component\HttpFoundation\HeaderUtils\makeDisposition
static makeDisposition(string $disposition, string $filename, string $filenameFallback='')
Definition: HeaderUtils.php:163