Open Journal Systems  3.3.0
SMime.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 
16 
22 abstract class SMime
23 {
24  protected function normalizeFilePath(string $path): string
25  {
26  if (!file_exists($path)) {
27  throw new RuntimeException(sprintf('File does not exist: "%s".', $path));
28  }
29 
30  return 'file://'.str_replace('\\', '/', realpath($path));
31  }
32 
33  protected function iteratorToFile(iterable $iterator, $stream): void
34  {
35  foreach ($iterator as $chunk) {
36  fwrite($stream, $chunk);
37  }
38  }
39 
40  protected function convertMessageToSMimePart($stream, string $type, string $subtype): SMimePart
41  {
42  rewind($stream);
43 
44  $headers = '';
45 
46  while (!feof($stream)) {
47  $buffer = fread($stream, 78);
48  $headers .= $buffer;
49 
50  // Detect ending of header list
51  if (preg_match('/(\r\n\r\n|\n\n)/', $headers, $match)) {
52  $headersPosEnd = strpos($headers, $headerBodySeparator = $match[0]);
53 
54  break;
55  }
56  }
57 
58  $headers = $this->getMessageHeaders(trim(substr($headers, 0, $headersPosEnd)));
59 
60  fseek($stream, $headersPosEnd + \strlen($headerBodySeparator));
61 
62  return new SMimePart($this->getStreamIterator($stream), $type, $subtype, $this->getParametersFromHeader($headers['content-type']));
63  }
64 
65  protected function getStreamIterator($stream): iterable
66  {
67  while (!feof($stream)) {
68  yield fread($stream, 16372);
69  }
70  }
71 
72  private function getMessageHeaders(string $headerData): array
73  {
74  $headers = [];
75  $headerLines = explode("\r\n", str_replace("\n", "\r\n", str_replace("\r\n", "\n", $headerData)));
76  $currentHeaderName = '';
77 
78  // Transform header lines into an associative array
79  foreach ($headerLines as $headerLine) {
80  // Empty lines between headers indicate a new mime-entity
81  if ('' === $headerLine) {
82  break;
83  }
84 
85  // Handle headers that span multiple lines
86  if (false === strpos($headerLine, ':')) {
87  $headers[$currentHeaderName] .= ' '.trim($headerLine);
88  continue;
89  }
90 
91  $header = explode(':', $headerLine, 2);
92  $currentHeaderName = strtolower($header[0]);
93  $headers[$currentHeaderName] = trim($header[1]);
94  }
95 
96  return $headers;
97  }
98 
99  private function getParametersFromHeader(string $header): array
100  {
101  $params = [];
102 
103  preg_match_all('/(?P<name>[a-z-0-9]+)=(?P<value>"[^"]+"|(?:[^\s;]+|$))(?:\s+;)?/i', $header, $matches);
104 
105  foreach ($matches['value'] as $pos => $paramValue) {
106  $params[$matches['name'][$pos]] = trim($paramValue, '"');
107  }
108 
109  return $params;
110  }
111 }
Symfony\Component\Mime\Exception\RuntimeException
Definition: vendor/symfony/mime/Exception/RuntimeException.php:17
Symfony\Component\Mime\Crypto\SMime\iteratorToFile
iteratorToFile(iterable $iterator, $stream)
Definition: SMime.php:33
Symfony\Component\Mime\Crypto\SMime\convertMessageToSMimePart
convertMessageToSMimePart($stream, string $type, string $subtype)
Definition: SMime.php:40
Symfony\Component\Mime\Crypto\SMime\getStreamIterator
getStreamIterator($stream)
Definition: SMime.php:65
Symfony\Component\Mime\Crypto
Definition: SMime.php:12
Symfony\Component\Mime\Crypto\SMime
Definition: SMime.php:22
Symfony\Component\Mime\Part\SMimePart
Definition: SMimePart.php:19
Symfony\Component\Mime\Crypto\SMime\normalizeFilePath
normalizeFilePath(string $path)
Definition: SMime.php:24