Passed
Push — master ( 37aad3...325143 )
by Zaahid
03:26
created

Message::getHtmlResourceHandle()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 2
dl 0
loc 7
ccs 5
cts 5
cp 1
crap 2
rs 10
c 0
b 0
f 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
namespace ZBateson\MailMimeParser;
8
9
use GuzzleHttp\Psr7;
10
use Psr\Http\Message\StreamInterface;
11
use ZBateson\MailMimeParser\Header\HeaderFactory;
12
use ZBateson\MailMimeParser\Message\Helper\MessageHelperService;
13
use ZBateson\MailMimeParser\Message\Part\MimePart;
14
use ZBateson\MailMimeParser\Message\Part\PartBuilder;
15
use ZBateson\MailMimeParser\Message\Part\PartStreamFilterManager;
16
use ZBateson\MailMimeParser\Message\PartFilter;
17
use ZBateson\MailMimeParser\Message\PartFilterFactory;
18
use ZBateson\MailMimeParser\Stream\StreamFactory;
19
20
/**
21
 * A parsed mime message with optional mime parts depending on its type.
22
 * 
23
 * A mime message may have any number of mime parts, and each part may have any
24
 * number of sub-parts, etc...
25
 *
26
 * @author Zaahid Bateson
27
 */
28
class Message extends MimePart
29
{
30
    /**
31
     * @var MessageHelperService helper class with various message manipulation
32
     *      routines.
33
     */
34
    protected $messageHelperService;
35
36
    /**
37
     * @param PartStreamFilterManager $partStreamFilterManager
38
     * @param StreamFactory $streamFactory
39
     * @param PartFilterFactory $partFilterFactory
40
     * @param HeaderFactory $headerFactory
41
     * @param PartBuilder $partBuilder
42
     * @param MessageHelperService $messageHelperService
43
     * @param StreamInterface $stream
44
     * @param StreamInterface $contentStream
45
     */
46 11
    public function __construct(
47
        PartStreamFilterManager $partStreamFilterManager,
48
        StreamFactory $streamFactory,
49
        PartFilterFactory $partFilterFactory,
50
        HeaderFactory $headerFactory,
51
        PartBuilder $partBuilder,
52
        MessageHelperService $messageHelperService,
53
        StreamInterface $stream = null,
54
        StreamInterface $contentStream = null
55
    ) {
56 11
        parent::__construct(
57 11
            $partStreamFilterManager,
58 11
            $streamFactory,
59 11
            $partFilterFactory,
60 11
            $headerFactory,
61 11
            $partBuilder,
62 11
            $stream,
63 11
            $contentStream
64
        );
65 11
        $this->messageHelperService = $messageHelperService;
66 11
    }
67
68
    /**
69
     * Convenience method to parse a handle or string into a Message without
70
     * requiring including MailMimeParser, instantiating it, and calling parse.
71
     * 
72
     * @param resource|string $handleOrString the resource handle to the input
73
     *        stream of the mime message, or a string containing a mime message
74
     */
75
    public static function from($handleOrString)
76
    {
77
        $mmp = new MailMimeParser();
78
        return $mmp->parse($handleOrString);
79
    }
80
81
    /**
82
     * Returns the text/plain part at the given index (or null if not found.)
83
     * 
84
     * @param int $index
85
     * @return \ZBateson\MailMimeParser\Message\Part\MimePart
86
     */
87 1
    public function getTextPart($index = 0)
88
    {
89 1
        return $this->getPart(
90 1
            $index,
91 1
            $this->partFilterFactory->newFilterFromInlineContentType('text/plain')
92
        );
93
    }
94
    
95
    /**
96
     * Returns the number of text/plain parts in this message.
97
     * 
98
     * @return int
99
     */
100 1
    public function getTextPartCount()
101
    {
102 1
        return $this->getPartCount(
103 1
            $this->partFilterFactory->newFilterFromInlineContentType('text/plain')
104
        );
105
    }
106
    
107
    /**
108
     * Returns the text/html part at the given index (or null if not found.)
109
     * 
110
     * @param $index
111
     * @return \ZBateson\MailMimeParser\Message\Part\MimePart
112
     */
113 1
    public function getHtmlPart($index = 0)
114
    {
115 1
        return $this->getPart(
116 1
            $index,
117 1
            $this->partFilterFactory->newFilterFromInlineContentType('text/html')
118
        );
119
    }
120
    
121
    /**
122
     * Returns the number of text/html parts in this message.
123
     * 
124
     * @return int
125
     */
126 1
    public function getHtmlPartCount()
127
    {
128 1
        return $this->getPartCount(
129 1
            $this->partFilterFactory->newFilterFromInlineContentType('text/html')
130
        );
131
    }
132
133
    /**
134
     * Returns the attachment part at the given 0-based index, or null if none
135
     * is set.
136
     * 
137
     * @param int $index
138
     * @return MessagePart
0 ignored issues
show
Bug introduced by
The type ZBateson\MailMimeParser\MessagePart was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
139
     */
140 1
    public function getAttachmentPart($index)
141
    {
142 1
        $attachments = $this->getAllAttachmentParts();
143 1
        if (!isset($attachments[$index])) {
144 1
            return null;
145
        }
146 1
        return $attachments[$index];
147
    }
148
149
    /**
150
     * Returns all attachment parts.
151
     * 
152
     * "Attachments" are any non-multipart, non-signature and any text or html
153
     * html part witha Content-Disposition set to  'attachment'.
154
     * 
155
     * @return MessagePart[]
156
     */
157 1
    public function getAllAttachmentParts()
158
    {
159 1
        $parts = $this->getAllParts(
160 1
            $this->partFilterFactory->newFilterFromArray([
161 1
                'multipart' => PartFilter::FILTER_EXCLUDE
162
            ])
163
        );
164 1
        return array_values(array_filter(
165 1
            $parts,
166 1
            function ($part) {
167
                return !(
168 1
                    $part->isTextPart()
169 1
                    && $part->getContentDisposition() === 'inline'
170
                );
171 1
            }
172
        ));
173
    }
174
175
    /**
176
     * Returns the number of attachments available.
177
     * 
178
     * @return int
179
     */
180 1
    public function getAttachmentCount()
181
    {
182 1
        return count($this->getAllAttachmentParts());
183
    }
184
185
    /**
186
     * Returns a Psr7 Stream for the 'inline' text/plain content at the passed
187
     * $index, or null if unavailable.
188
     * 
189
     * @param int $index
190
     * @param string $charset
191
     * @return StreamInterface
192
     */
193 1
    public function getTextStream($index = 0, $charset = MailMimeParser::DEFAULT_CHARSET)
194
    {
195 1
        $textPart = $this->getTextPart($index);
196 1
        if ($textPart !== null) {
197 1
            return $textPart->getContentStream($charset);
198
        }
199 1
        return null;
200
    }
201
202
    /**
203
     * Returns a resource handle for the 'inline' text/plain content at the
204
     * passed $index, or null if unavailable.
205
     *
206
     * @param int $index
207
     * @param string $charset
208
     * @return resource
209
     */
210 1
    public function getTextResourceHandle($index = 0, $charset = MailMimeParser::DEFAULT_CHARSET)
211
    {
212 1
        $textPart = $this->getTextPart($index);
213 1
        if ($textPart !== null) {
214 1
            return $textPart->getContentResourceHandle($charset);
215
        }
216 1
        return null;
217
    }
218
219
    /**
220
     * Returns the content of the inline text/plain part at the given index.
221
     * 
222
     * Reads the entire stream content into a string and returns it.  Returns
223
     * null if the message doesn't have an inline text part.
224
     * 
225
     * @param int $index
226
     * @param string $charset
227
     * @return string
228
     */
229 1
    public function getTextContent($index = 0, $charset = MailMimeParser::DEFAULT_CHARSET)
230
    {
231 1
        $part = $this->getTextPart($index);
232 1
        if ($part !== null) {
233 1
            return $part->getContent($charset);
234
        }
235 1
        return null;
236
    }
237
238
    /**
239
     * Returns a Psr7 Stream for the 'inline' text/html content at the passed
240
     * $index, or null if unavailable.
241
     * 
242
     * @param int $index
243
     * @param string $charset
244
     * @return resource
245
     */
246 1
    public function getHtmlStream($index = 0, $charset = MailMimeParser::DEFAULT_CHARSET)
247
    {
248 1
        $htmlPart = $this->getHtmlPart($index);
249 1
        if ($htmlPart !== null) {
250 1
            return $htmlPart->getContentStream($charset);
251
        }
252 1
        return null;
253
    }
254
255
    /**
256
     * Returns a resource handle for the 'inline' text/html content at the
257
     * passed $index, or null if unavailable.
258
     *
259
     * @param int $index
260
     * @param string $charset
261
     * @return resource
262
     */
263 1
    public function getHtmlResourceHandle($index = 0, $charset = MailMimeParser::DEFAULT_CHARSET)
264
    {
265 1
        $htmlPart = $this->getHtmlPart($index);
266 1
        if ($htmlPart !== null) {
267 1
            return $htmlPart->getContentResourceHandle($charset);
268
        }
269 1
        return null;
270
    }
271
272
    /**
273
     * Returns the content of the inline text/html part at the given index.
274
     * 
275
     * Reads the entire stream content into a string and returns it.  Returns
276
     * null if the message doesn't have an inline html part.
277
     * 
278
     * @param int $index
279
     * @param string $charset
280
     * @return string
281
     */
282 1
    public function getHtmlContent($index = 0, $charset = MailMimeParser::DEFAULT_CHARSET)
283
    {
284 1
        $part = $this->getHtmlPart($index);
285 1
        if ($part !== null) {
286 1
            return $part->getContent($charset);
287
        }
288 1
        return null;
289
    }
290
291
    /**
292
     * Returns true if either a Content-Type or Mime-Version header are defined
293
     * in this Message.
294
     * 
295
     * @return bool
296
     */
297 3
    public function isMime()
298
    {
299 3
        $contentType = $this->getHeaderValue('Content-Type');
300 3
        $mimeVersion = $this->getHeaderValue('Mime-Version');
301 3
        return ($contentType !== null || $mimeVersion !== null);
302
    }
303
304
    /**
305
     * Sets the text/plain part of the message to the passed $stringOrHandle,
306
     * either creating a new part if one doesn't exist for text/plain, or
307
     * assigning the value of $stringOrHandle to an existing text/plain part.
308
     *
309
     * The optional $charset parameter is the charset for saving to.
310
     * $stringOrHandle is expected to be in UTF-8 regardless of the target
311
     * charset.
312
     *
313
     * @param string|resource|StreamInterface $resource
314
     * @param string $charset
315
     */
316 1
    public function setTextPart($resource, $charset = 'UTF-8')
317
    {
318 1
        $this->messageHelperService
319 1
            ->getMultipartHelper()
320 1
            ->setContentPartForMimeType(
321 1
                $this, 'text/plain', $resource, $charset
322
            );
323 1
    }
324
325
    /**
326
     * Sets the text/html part of the message to the passed $stringOrHandle,
327
     * either creating a new part if one doesn't exist for text/html, or
328
     * assigning the value of $stringOrHandle to an existing text/html part.
329
     *
330
     * The optional $charset parameter is the charset for saving to.
331
     * $stringOrHandle is expected to be in UTF-8 regardless of the target
332
     * charset.
333
     *
334
     * @param string|resource|StreamInterface $resource
335
     * @param string $charset
336
     */
337 1
    public function setHtmlPart($resource, $charset = 'UTF-8')
338
    {
339 1
        $this->messageHelperService
340 1
            ->getMultipartHelper()
341 1
            ->setContentPartForMimeType(
342 1
                $this, 'text/html', $resource, $charset
343
            );
344 1
    }
345
346
    /**
347
     * Removes the text/plain part of the message at the passed index if one
348
     * exists.  Returns true on success.
349
     *
350
     * @return bool true on success
351
     */
352 1
    public function removeTextPart($index = 0)
353
    {
354 1
        return $this->messageHelperService
355 1
            ->getMultipartHelper()
356 1
            ->removePartByMimeType(
357 1
                $this, 'text/plain', $index
358
            );
359
    }
360
361
    /**
362
     * Removes all text/plain inline parts in this message, optionally keeping
363
     * other inline parts as attachments on the main message (defaults to
364
     * keeping them).
365
     *
366
     * @param bool $keepOtherPartsAsAttachments
367
     * @return bool true on success
368
     */
369 1
    public function removeAllTextParts($keepOtherPartsAsAttachments = true)
370
    {
371 1
        return $this->messageHelperService
372 1
            ->getMultipartHelper()
373 1
            ->removeAllContentPartsByMimeType(
374 1
                $this, 'text/plain', $keepOtherPartsAsAttachments
375
            );
376
    }
377
378
    /**
379
     * Removes the html part of the message if one exists.  Returns true on
380
     * success.
381
     *
382
     * @return bool true on success
383
     */
384 1
    public function removeHtmlPart($index = 0)
385
    {
386 1
        return $this->messageHelperService
387 1
            ->getMultipartHelper()
388 1
            ->removePartByMimeType(
389 1
                $this, 'text/html', $index
390
            );
391
    }
392
393
    /**
394
     * Removes all text/html inline parts in this message, optionally keeping
395
     * other inline parts as attachments on the main message (defaults to
396
     * keeping them).
397
     *
398
     * @param bool $keepOtherPartsAsAttachments
399
     * @return bool true on success
400
     */
401 1
    public function removeAllHtmlParts($keepOtherPartsAsAttachments = true)
402
    {
403 1
        return $this->messageHelperService
404 1
            ->getMultipartHelper()
405 1
            ->removeAllContentPartsByMimeType(
406 1
                $this, 'text/html', $keepOtherPartsAsAttachments
407
            );
408
    }
409
410
    /**
411
     * Adds an attachment part for the passed raw data string or handle and
412
     * given parameters.
413
     *
414
     * @param string|resource|StreamInterface $resource
415
     * @param strubg $mimeType
0 ignored issues
show
Bug introduced by
The type ZBateson\MailMimeParser\strubg was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
416
     * @param string $filename
417
     * @param string $disposition
418
     */
419 1
    public function addAttachmentPart($resource, $mimeType, $filename = null, $disposition = 'attachment')
420
    {
421 1
        $this->messageHelperService
422 1
            ->getMultipartHelper()
423 1
            ->createAndAddPartForAttachment($this, $resource, $mimeType, $filename, $disposition);
424 1
    }
425
426
    /**
427
     * Adds an attachment part using the passed file.
428
     *
429
     * Essentially creates a file stream and uses it.
430
     *
431
     * @param string $filePath
432
     * @param string $mimeType
433
     * @param string $filename
434
     * @param string $disposition
435
     */
436 1
    public function addAttachmentPartFromFile($filePath, $mimeType, $filename = null, $disposition = 'attachment')
437
    {
438 1
        $handle = Psr7\stream_for(fopen($filePath, 'r'));
0 ignored issues
show
Bug introduced by
The function stream_for was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

438
        $handle = /** @scrutinizer ignore-call */ Psr7\stream_for(fopen($filePath, 'r'));
Loading history...
439 1
        if ($filename === null) {
440 1
            $filename = basename($filePath);
441
        }
442 1
        $this->addAttachmentPart($handle, $mimeType, $filename, $disposition);
0 ignored issues
show
Bug introduced by
$mimeType of type string is incompatible with the type ZBateson\MailMimeParser\strubg expected by parameter $mimeType of ZBateson\MailMimeParser\...ge::addAttachmentPart(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

442
        $this->addAttachmentPart($handle, /** @scrutinizer ignore-type */ $mimeType, $filename, $disposition);
Loading history...
443 1
    }
444
445
    /**
446
     * Removes the attachment with the given index
447
     *
448
     * @param int $index
449
     */
450 1
    public function removeAttachmentPart($index)
451
    {
452 1
        $part = $this->getAttachmentPart($index);
453 1
        $this->removePart($part);
454 1
    }
455
456
    /**
457
     * Returns a stream that can be used to read the content part of a signed
458
     * message, which can be used to sign an email or verify a signature.
459
     *
460
     * The method simply returns the stream for the first child.  No
461
     * verification of whether the message is in fact a signed message is
462
     * performed.
463
     *
464
     * Note that unlike getSignedMessageAsString, getSignedMessageStream doesn't
465
     * replace new lines.
466
     *
467
     * @return StreamInterface or null if the message doesn't have any children
468
     */
469 1
    public function getSignedMessageStream()
470
    {
471
        return $this
472 1
            ->messageHelperService
473 1
            ->getPrivacyHelper()
474 1
            ->getSignedMessageStream($this);
475
    }
476
477
    /**
478
     * Returns a string containing the entire body of a signed message for
479
     * verification or calculating a signature.
480
     *
481
     * Non-CRLF new lines are replaced to always be CRLF.
482
     *
483
     * @return string or null if the message doesn't have any children
484
     */
485 1
    public function getSignedMessageAsString()
486
    {
487
        return $this
488 1
            ->messageHelperService
489 1
            ->getPrivacyHelper()
490 1
            ->getSignedMessageAsString($this);
491
    }
492
493
    /**
494
     * Returns the signature part of a multipart/signed message or null.
495
     *
496
     * The signature part is determined to always be the 2nd child of a
497
     * multipart/signed message, the first being the 'body'.
498
     *
499
     * Using the 'protocol' parameter of the Content-Type header is unreliable
500
     * in some instances (for instance a difference of x-pgp-signature versus
501
     * pgp-signature).
502
     *
503
     * @return MimePart
504
     */
505
    public function getSignaturePart()
506
    {
507
        return $this
508
            ->messageHelperService
509
            ->getPrivacyHelper()
510
            ->getSignaturePart($this);
511
    }
512
513
    /**
514
     * Turns the message into a multipart/signed message, moving the actual
515
     * message into a child part, sets the content-type of the main message to
516
     * multipart/signed and adds an empty signature part as well.
517
     *
518
     * After calling setAsMultipartSigned, call getSignedMessageAsString to
519
     * return a
520
     *
521
     * @param string $micalg The Message Integrity Check algorithm being used
522
     * @param string $protocol The mime-type of the signature body
523
     */
524 1
    public function setAsMultipartSigned($micalg, $protocol)
525
    {
526
        $this
527 1
            ->messageHelperService
528 1
            ->getPrivacyHelper()
529 1
            ->setMessageAsMultipartSigned($this, $micalg, $protocol);
530 1
    }
531
532
    /**
533
     * Sets the signature body of the message to the passed $body for a
534
     * multipart/signed message.
535
     *
536
     * @param string $body
537
     */
538 1
    public function setSignature($body)
539
    {
540 1
        $this->messageHelperService->getPrivacyHelper()
541 1
            ->setSignature($this, $body);
542 1
    }
543
}
544