Open Journal Systems  3.3.0
TextPart.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 
24 class TextPart extends AbstractPart
25 {
26  private static $encoders = [];
27 
28  private $body;
29  private $charset;
30  private $subtype;
31  private $disposition;
32  private $name;
33  private $encoding;
34 
38  public function __construct($body, ?string $charset = 'utf-8', $subtype = 'plain', string $encoding = null)
39  {
40  parent::__construct();
41 
42  if (!\is_string($body) && !\is_resource($body)) {
43  throw new \TypeError(sprintf('The body of "%s" must be a string or a resource (got "%s").', self::class, \is_object($body) ? \get_class($body) : \gettype($body)));
44  }
45 
46  $this->body = $body;
47  $this->charset = $charset;
48  $this->subtype = $subtype;
49 
50  if (null === $encoding) {
51  $this->encoding = $this->chooseEncoding();
52  } else {
53  if ('quoted-printable' !== $encoding && 'base64' !== $encoding && '8bit' !== $encoding) {
54  throw new InvalidArgumentException(sprintf('The encoding must be one of "quoted-printable", "base64", or "8bit" ("%s" given).', $encoding));
55  }
56  $this->encoding = $encoding;
57  }
58  }
59 
60  public function getMediaType(): string
61  {
62  return 'text';
63  }
64 
65  public function getMediaSubtype(): string
66  {
67  return $this->subtype;
68  }
69 
75  public function setDisposition(string $disposition)
76  {
77  $this->disposition = $disposition;
78 
79  return $this;
80  }
81 
87  public function setName($name)
88  {
89  $this->name = $name;
90 
91  return $this;
92  }
93 
94  public function getBody(): string
95  {
96  if (!\is_resource($this->body)) {
97  return $this->body;
98  }
99 
100  if (stream_get_meta_data($this->body)['seekable'] ?? false) {
101  rewind($this->body);
102  }
103 
104  return stream_get_contents($this->body) ?: '';
105  }
106 
107  public function bodyToString(): string
108  {
109  return $this->getEncoder()->encodeString($this->getBody(), $this->charset);
110  }
111 
112  public function bodyToIterable(): iterable
113  {
114  if (\is_resource($this->body)) {
115  if (stream_get_meta_data($this->body)['seekable'] ?? false) {
116  rewind($this->body);
117  }
118  yield from $this->getEncoder()->encodeByteStream($this->body);
119  } else {
120  yield $this->getEncoder()->encodeString($this->body);
121  }
122  }
123 
124  public function getPreparedHeaders(): Headers
125  {
126  $headers = parent::getPreparedHeaders();
127 
128  $headers->setHeaderBody('Parameterized', 'Content-Type', $this->getMediaType().'/'.$this->getMediaSubtype());
129  if ($this->charset) {
130  $headers->setHeaderParameter('Content-Type', 'charset', $this->charset);
131  }
132  if ($this->name) {
133  $headers->setHeaderParameter('Content-Type', 'name', $this->name);
134  }
135  $headers->setHeaderBody('Text', 'Content-Transfer-Encoding', $this->encoding);
136 
137  if (!$headers->has('Content-Disposition') && null !== $this->disposition) {
138  $headers->setHeaderBody('Parameterized', 'Content-Disposition', $this->disposition);
139  if ($this->name) {
140  $headers->setHeaderParameter('Content-Disposition', 'name', $this->name);
141  }
142  }
143 
144  return $headers;
145  }
146 
147  public function asDebugString(): string
148  {
149  $str = parent::asDebugString();
150  if (null !== $this->charset) {
151  $str .= ' charset: '.$this->charset;
152  }
153  if (null !== $this->disposition) {
154  $str .= ' disposition: '.$this->disposition;
155  }
156 
157  return $str;
158  }
159 
160  private function getEncoder(): ContentEncoderInterface
161  {
162  if ('8bit' === $this->encoding) {
163  return self::$encoders[$this->encoding] ?? (self::$encoders[$this->encoding] = new EightBitContentEncoder());
164  }
165 
166  if ('quoted-printable' === $this->encoding) {
167  return self::$encoders[$this->encoding] ?? (self::$encoders[$this->encoding] = new QpContentEncoder());
168  }
169 
170  return self::$encoders[$this->encoding] ?? (self::$encoders[$this->encoding] = new Base64ContentEncoder());
171  }
172 
173  private function chooseEncoding(): string
174  {
175  if (null === $this->charset) {
176  return 'base64';
177  }
178 
179  return 'quoted-printable';
180  }
181 
185  public function __sleep()
186  {
187  // convert resources to strings for serialization
188  if (\is_resource($this->body)) {
189  $this->body = $this->getBody();
190  }
191 
192  $this->_headers = $this->getHeaders();
193 
194  return ['_headers', 'body', 'charset', 'subtype', 'disposition', 'name', 'encoding'];
195  }
196 
197  public function __wakeup()
198  {
199  $r = new \ReflectionProperty(AbstractPart::class, 'headers');
200  $r->setAccessible(true);
201  $r->setValue($this, $this->_headers);
202  unset($this->_headers);
203  }
204 }
Symfony\Component\Mime\Part\AbstractPart\getHeaders
getHeaders()
Definition: AbstractPart.php:28
Symfony\Component\Mime\Part\TextPart\__sleep
__sleep()
Definition: TextPart.php:185
Symfony\Component\Mime\Part\TextPart\getPreparedHeaders
getPreparedHeaders()
Definition: TextPart.php:124
Symfony\Component\Mime\Part\TextPart\asDebugString
asDebugString()
Definition: TextPart.php:147
Symfony\Component\Mime\Encoder\QpContentEncoder
Definition: QpContentEncoder.php:17
Symfony\Component\Mime\Part\TextPart\getMediaType
getMediaType()
Definition: TextPart.php:60
Symfony\Component\Mime\Part\TextPart\__wakeup
__wakeup()
Definition: TextPart.php:197
Symfony\Component\Mime\Encoder\Base64ContentEncoder
Definition: Base64ContentEncoder.php:19
Symfony\Component\Mime\Part
Definition: AbstractMultipartPart.php:12
Symfony\Component\Mime\Part\TextPart\setDisposition
setDisposition(string $disposition)
Definition: TextPart.php:75
Symfony\Component\Mime\Part\AbstractPart
Definition: AbstractPart.php:19
Symfony\Component\Mime\Part\TextPart\bodyToIterable
bodyToIterable()
Definition: TextPart.php:112
Symfony\Component\Mime\Part\TextPart
Definition: TextPart.php:24
Symfony\Component\Mime\Encoder\EightBitContentEncoder
Definition: EightBitContentEncoder.php:17
Symfony\Component\Mime\Exception\InvalidArgumentException
Definition: vendor/symfony/mime/Exception/InvalidArgumentException.php:17
Symfony\Component\Mime\Header\Headers
Definition: Headers.php:22
Symfony\Component\Mime\Part\TextPart\setName
setName($name)
Definition: TextPart.php:87
Symfony\Component\Mime\Encoder\ContentEncoderInterface
Definition: ContentEncoderInterface.php:17
Symfony\Component\Mime\Part\TextPart\bodyToString
bodyToString()
Definition: TextPart.php:107
Symfony\Component\Mime\Part\TextPart\getMediaSubtype
getMediaSubtype()
Definition: TextPart.php:65
Symfony\Component\Mime\Part\TextPart\__construct
__construct($body, ?string $charset='utf-8', $subtype='plain', string $encoding=null)
Definition: TextPart.php:38
Symfony\Component\Mime\Part\TextPart\getBody
getBody()
Definition: TextPart.php:94