PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 11.1.1
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v11.1.1
11.1.1 11.1.0 11.0.5 11.0.4 11.0.3 11.0.2 11.0.1 11.0.0 10.11.1 10.11.0 10.10.2 10.10.1 10.10.0 10.9.1 trunk 10.0.0 10.0.1 10.1.0 10.1.1 10.1.2 10.1.3 10.1.4 10.2.0 10.2.1 10.2.2 All 62 releases
← All changes | vendor/zbateson/mail-mime-parser/src/Message/PartStreamContainer.php +0 -303 trunk → 11.1.1 View file →
@@ -1,303 +1,0 @@
1 -<?php
2 -/**
3 - * This file is part of the ZBateson\MailMimeParser project.
4 - *
5 - * @license http://opensource.org/licenses/bsd-license.php BSD
6 - */
7 -
8 -namespace ZBateson\MailMimeParser\Message;
9 -
10 -use GuzzleHttp\Psr7\CachingStream;
11 -use Psr\Http\Message\StreamInterface;
12 -use ZBateson\MailMimeParser\Stream\StreamFactory;
13 -
14 -/**
15 - * Holds the stream and content stream objects for a part.
16 - *
17 - * Note that streams are not explicitly closed or detached on destruction of the
18 - * PartSreamContainer by design: the passed StreamInterfaces will be closed on
19 - * their destruction when no references to them remain, which is useful when the
20 - * streams are passed around.
21 - *
22 - * In addition, all the streams passed to PartStreamContainer should be wrapping
23 - * a ZBateson\StreamDecorators\NonClosingStream unless attached to a part by a
24 - * user, this is because MMP uses a single seekable stream for content and wraps
25 - * it in ZBateson\StreamDecorators\SeekingLimitStream objects for each part.
26 - *
27 - * @author Zaahid Bateson
28 - */
29 -class PartStreamContainer
30 -{
31 - /**
32 - * @var StreamFactory used to apply psr7 stream decorators to the
33 - * attached StreamInterface based on encoding.
34 - */
35 - protected $streamFactory;
36 -
37 - /**
38 - * @var StreamInterface stream containing the part's headers, content and
39 - * children
40 - */
41 - protected $stream;
42 -
43 - /**
44 - * @var StreamInterface a stream containing this part's content
45 - */
46 - protected $contentStream;
47 -
48 - /**
49 - * @var StreamInterface the content stream after attaching transfer encoding
50 - * streams to $contentStream.
51 - */
52 - protected $decodedStream;
53 -
54 - /**
55 - * @var StreamInterface attached charset stream to $decodedStream
56 - */
57 - protected $charsetStream;
58 -
59 - /**
60 - * @var bool true if the stream should be detached when this container is
61 - * destroyed.
62 - */
63 - protected $detachParsedStream;
64 -
65 - /**
66 - * @var array<string, null> map of the active encoding filter on the current handle.
67 - */
68 - private $encoding = [
69 - 'type' => null,
70 - 'filter' => null
71 - ];
72 -
73 - /**
74 - * @var array<string, null> map of the active charset filter on the current handle.
75 - */
76 - private $charset = [
77 - 'from' => null,
78 - 'to' => null,
79 - 'filter' => null
80 - ];
81 -
82 - public function __construct(StreamFactory $streamFactory)
83 - {
84 - $this->streamFactory = $streamFactory;
85 - }
86 -
87 - /**
88 - * Sets the part's stream containing the part's headers, content, and
89 - * children.
90 - *
91 - */
92 - public function setStream(StreamInterface $stream)
93 - {
94 - $this->stream = $stream;
95 - }
96 -
97 - /**
98 - * Returns the part's stream containing the part's headers, content, and
99 - * children.
100 - *
101 - * @return StreamInterface
102 - */
103 - public function getStream()
104 - {
105 - // error out if called before setStream, getStream should never return
106 - // null.
107 - $this->stream->rewind();
108 - return $this->stream;
109 - }
110 -
111 - /**
112 - * Returns true if there's a content stream associated with the part.
113 - *
114 - */
115 - public function hasContent() : bool
116 - {
117 - return ($this->contentStream !== null);
118 - }
119 -
120 - /**
121 - * Attaches the passed stream as the content portion of this
122 - * StreamContainer.
123 - *
124 - * The content stream would represent the content portion of $this->stream.
125 - *
126 - * If the content is overridden, $this->stream should point to a dynamic
127 - * {@see ZBateson\Stream\MessagePartStream} that dynamically creates the
128 - * RFC822 formatted message based on the IMessagePart this
129 - * PartStreamContainer belongs to.
130 - *
131 - * setContentStream can be called with 'null' to indicate the IMessagePart
132 - * does not contain any content.
133 - *
134 - * @param StreamInterface $contentStream
135 - */
136 - public function setContentStream(?StreamInterface $contentStream = null)
137 - {
138 - $this->contentStream = $contentStream;
139 - $this->decodedStream = null;
140 - $this->charsetStream = null;
141 - }
142 -
143 - /**
144 - * Returns true if the attached stream filter used for decoding the content
145 - * on the current handle is different from the one passed as an argument.
146 - *
147 - * @param string $transferEncoding
148 - */
149 - private function isTransferEncodingFilterChanged(?string $transferEncoding) : bool
150 - {
151 - return ($transferEncoding !== $this->encoding['type']);
152 - }
153 -
154 - /**
155 - * Returns true if the attached stream filter used for charset conversion on
156 - * the current handle is different from the one needed based on the passed
157 - * arguments.
158 - *
159 - */
160 - private function isCharsetFilterChanged(string $fromCharset, string $toCharset) : bool
161 - {
162 - return ($fromCharset !== $this->charset['from']
163 - || $toCharset !== $this->charset['to']);
164 - }
165 -
166 - /**
167 - * Attaches a decoding filter to the attached content handle, for the passed
168 - * $transferEncoding.
169 - *
170 - * @param string $transferEncoding
171 - */
172 - protected function attachTransferEncodingFilter(?string $transferEncoding) : self
173 - {
174 - if ($this->decodedStream !== null) {
175 - $this->encoding['type'] = $transferEncoding;
176 - $assign = null;
177 - switch ($transferEncoding) {
178 - case 'base64':
179 - $assign = $this->streamFactory->newBase64Stream($this->decodedStream);
180 - break;
181 - case 'x-uuencode':
182 - $assign = $this->streamFactory->newUUStream($this->decodedStream);
183 - break;
184 - case 'quoted-printable':
185 - $assign = $this->streamFactory->newQuotedPrintableStream($this->decodedStream);
186 - break;
187 - }
188 - if ($assign !== null) {
189 - $this->decodedStream = new CachingStream($assign);
190 - }
191 - }
192 - return $this;
193 - }
194 -
195 - /**
196 - * Attaches a charset conversion filter to the attached content handle, for
197 - * the passed arguments.
198 - *
199 - * @param string $fromCharset the character set the content is encoded in
200 - * @param string $toCharset the target encoding to return
201 - */
202 - protected function attachCharsetFilter(string $fromCharset, string $toCharset) : self
203 - {
204 - if ($this->charsetStream !== null) {
205 - $this->charsetStream = new CachingStream($this->streamFactory->newCharsetStream(
206 - $this->charsetStream,
207 - $fromCharset,
208 - $toCharset
209 - ));
210 - $this->charset['from'] = $fromCharset;
211 - $this->charset['to'] = $toCharset;
212 - }
213 - return $this;
214 - }
215 -
216 - /**
217 - * Resets just the charset stream, and rewinds the decodedStream.
218 - */
219 - private function resetCharsetStream() : self
220 - {
221 - $this->charset = [
222 - 'from' => null,
223 - 'to' => null,
224 - 'filter' => null
225 - ];
226 - $this->decodedStream->rewind();
227 - $this->charsetStream = $this->decodedStream;
228 - return $this;
229 - }
230 -
231 - /**
232 - * Resets cached encoding and charset streams, and rewinds the stream.
233 - */
234 - public function reset()
235 - {
236 - $this->encoding = [
237 - 'type' => null,
238 - 'filter' => null
239 - ];
240 - $this->charset = [
241 - 'from' => null,
242 - 'to' => null,
243 - 'filter' => null
244 - ];
245 - $this->contentStream->rewind();
246 - $this->decodedStream = $this->contentStream;
247 - $this->charsetStream = $this->contentStream;
248 - }
249 -
250 - /**
251 - * Checks what transfer-encoding decoder stream and charset conversion
252 - * stream are currently attached on the underlying contentStream, and resets
253 - * them if the requested arguments differ from the currently assigned ones.
254 - *
255 - * @param string $transferEncoding the transfer encoding
256 - * @param string $fromCharset the character set the content is encoded in
257 - * @param string $toCharset the target encoding to return
258 - * @return ?StreamInterface
259 - */
260 - public function getContentStream(?string $transferEncoding, ?string $fromCharset, ?string $toCharset)
261 - {
262 - if ($this->contentStream === null) {
263 - return null;
264 - }
265 - if (empty($fromCharset) || empty($toCharset)) {
266 - return $this->getBinaryContentStream($transferEncoding);
267 - }
268 - if ($this->charsetStream === null
269 - || $this->isTransferEncodingFilterChanged($transferEncoding)
270 - || $this->isCharsetFilterChanged($fromCharset, $toCharset)) {
271 - if ($this->charsetStream === null
272 - || $this->isTransferEncodingFilterChanged($transferEncoding)) {
273 - $this->reset();
274 - $this->attachTransferEncodingFilter($transferEncoding);
275 - }
276 - $this->resetCharsetStream();
277 - $this->attachCharsetFilter($fromCharset, $toCharset);
278 - }
279 - $this->charsetStream->rewind();
280 - return $this->charsetStream;
281 - }
282 -
283 - /**
284 - * Checks what transfer-encoding decoder stream is attached on the
285 - * underlying stream, and resets it if the requested arguments differ.
286 - *
287 - * @param string $transferEncoding
288 - * @return StreamInterface
289 - */
290 - public function getBinaryContentStream(?string $transferEncoding = null) : ?StreamInterface
291 - {
292 - if ($this->contentStream === null) {
293 - return null;
294 - }
295 - if ($this->decodedStream === null
296 - || $this->isTransferEncodingFilterChanged($transferEncoding)) {
297 - $this->reset();
298 - $this->attachTransferEncodingFilter($transferEncoding);
299 - }
300 - $this->decodedStream->rewind();
301 - return $this->decodedStream;
302 - }
303 -}