Passed
Push — master ( c6b62f...37aad3 )
by Zaahid
03:17
created

Message::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 8
dl 0
loc 20
ccs 10
cts 10
cp 1
crap 1
rs 9.9666
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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\StreamWrapper;
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 10
    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 10
        parent::__construct(
57 10
            $partStreamFilterManager,
58 10
            $streamFactory,
59 10
            $partFilterFactory,
60 10
            $headerFactory,
61 10
            $partBuilder,
62 10
            $stream,
63 10
            $contentStream
64
        );
65 10
        $this->messageHelperService = $messageHelperService;
66 10
    }
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
    public function getTextResourceHandle($index = 0, $charset = MailMimeParser::DEFAULT_CHARSET)
211
    {
212
        $stream = $this->getTextStream($index, $charset);
213
        if ($stream !== null) {
214
            return StreamWrapper::getResource($stream);
215
        }
216
        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
    public function getHtmlResourceHandle($index = 0, $charset = MailMimeParser::DEFAULT_CHARSET)
264
    {
265
        $stream = $this->getHtmlStream($index, $charset);
266
        if ($stream !== null) {
0 ignored issues
show
introduced by
The condition $stream !== null is always true.
Loading history...
267
            return StreamWrapper::getResource($stream);
0 ignored issues
show
Bug introduced by
$stream of type resource is incompatible with the type Psr\Http\Message\StreamInterface expected by parameter $stream of GuzzleHttp\Psr7\StreamWrapper::getResource(). ( Ignorable by Annotation )

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

267
            return StreamWrapper::getResource(/** @scrutinizer ignore-type */ $stream);
Loading history...
268
        }
269
        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
    public function setTextPart($resource, $charset = 'UTF-8')
317
    {
318
        $this->messageHelperService
319
            ->getMultipartHelper()
320
            ->setContentPartForMimeType(
321
                $this, 'text/plain', $resource, $charset
322
            );
323
    }
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
    public function setHtmlPart($resource, $charset = 'UTF-8')
338
    {
339
        $this->messageHelperService
340
            ->getMultipartHelper()
341
            ->setContentPartForMimeType(
342
                $this, 'text/html', $resource, $charset
343
            );
344
    }
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
    public function removeTextPart($index = 0)
353
    {
354
        return $this->messageHelperService
355
            ->getMultipartHelper()
356
            ->removePartByMimeType(
357
                $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
    public function removeAllTextParts($keepOtherPartsAsAttachments = true)
370
    {
371
        return $this->messageHelperService
372
            ->getMultipartHelper()
373
            ->removeAllContentPartsByMimeType(
374
                $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
    public function removeHtmlPart($index = 0)
385
    {
386
        return $this->messageHelperService
387
            ->getMultipartHelper()
388
            ->removePartByMimeType(
389
                $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
    public function removeAllHtmlParts($keepOtherPartsAsAttachments = true)
402
    {
403
        return $this->messageHelperService
404
            ->getMultipartHelper()
405
            ->removeAllContentPartsByMimeType(
406
                $this, 'text/html', $keepOtherPartsAsAttachments
407
            );
408
    }
409
410
    /**
411
     * Removes the attachment with the given index
412
     *
413
     * @param int $index
414
     */
415
    public function removeAttachmentPart($index)
416
    {
417
        $part = $this->getAttachmentPart($index);
418
        $this->removePart($part);
419
    }
420
421
    /**
422
     * Adds an attachment part for the passed raw data string or handle and
423
     * given parameters.
424
     *
425
     * @param string|handle $stringOrHandle
0 ignored issues
show
Bug introduced by
The type ZBateson\MailMimeParser\handle 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...
426
     * @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...
427
     * @param string $filename
428
     * @param string $disposition
429
     */
430
    public function addAttachmentPart($stringOrHandle, $mimeType, $filename = null, $disposition = 'attachment')
431
    {
432
        if ($filename === null) {
433
            $filename = 'file' . uniqid();
434
        }
435
        $part = $this->messageHelperService
436
            ->getMultipartHelper()
437
            ->createPartForAttachment($this, $mimeType, $filename, $disposition);
438
        $part->setContent($stringOrHandle);
439
        $this->addChild($part);
440
    }
441
442
    /**
443
     * Adds an attachment part using the passed file.
444
     *
445
     * Essentially creates a file stream and uses it.
446
     *
447
     * @param string $file
448
     * @param string $mimeType
449
     * @param string $filename
450
     * @param string $disposition
451
     */
452
    public function addAttachmentPartFromFile($file, $mimeType, $filename = null, $disposition = 'attachment')
453
    {
454
        $handle = fopen($file, 'r');
455
        if ($filename === null) {
456
            $filename = basename($file);
457
        }
458
        $this->addAttachmentPart($handle, $mimeType, $filename, $disposition);
0 ignored issues
show
Bug introduced by
$handle of type resource|false is incompatible with the type ZBateson\MailMimeParser\handle|string expected by parameter $stringOrHandle 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

458
        $this->addAttachmentPart(/** @scrutinizer ignore-type */ $handle, $mimeType, $filename, $disposition);
Loading history...
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

458
        $this->addAttachmentPart($handle, /** @scrutinizer ignore-type */ $mimeType, $filename, $disposition);
Loading history...
459
    }
460
461
    /**
462
     * Returns a string containing the entire body of a signed message for
463
     * verification or calculating a signature.
464
     *
465
     * @return string or null if the message doesn't have any children
466
     */
467 2
    public function getSignedMessageAsString()
468
    {
469 2
        $child = $this->getChild(0);
470 2
        if ($child !== null) {
471 1
            $normalized = preg_replace(
472 1
                '/\r\n|\r|\n/',
473 1
                "\r\n",
474 1
                $child->getStream()->getContents()
475
            );
476 1
            return $normalized;
477
        }
478 1
        return null;
479
    }
480
481
    /**
482
     * Returns the signature part of a multipart/signed message or null.
483
     *
484
     * The signature part is determined to always be the 2nd child of a
485
     * multipart/signed message, the first being the 'body'.
486
     *
487
     * Using the 'protocol' parameter of the Content-Type header is unreliable
488
     * in some instances (for instance a difference of x-pgp-signature versus
489
     * pgp-signature).
490
     *
491
     * @return MimePart
492
     */
493
    public function getSignaturePart()
494
    {
495
        $contentType = $this->getHeaderValue('Content-Type', 'text/plain');
496
        if (strcasecmp($contentType, 'multipart/signed') === 0) {
497
            return $this->getChild(1);
498
        } else {
499
            return null;
500
        }
501
    }
502
503
    /**
504
     * Turns the message into a multipart/signed message, moving the actual
505
     * message into a child part, sets the content-type of the main message to
506
     * multipart/signed and adds an empty signature part as well.
507
     *
508
     * After calling setAsMultipartSigned, call get
509
     *
510
     * @param string $micalg The Message Integrity Check algorithm being used
511
     * @param string $protocol The mime-type of the signature body
512
     */
513
    public function setAsMultipartSigned($micalg, $protocol)
514
    {
515
        $contentType = $this->getHeaderValue('Content-Type', 'text/plain');
516
        if (strcasecmp($contentType, 'multipart/signed') !== 0) {
517
            $this->messageHelperService->getPrivacyHelper()
518
                ->setMessageAsMultipartSigned($this, $micalg, $protocol);
519
        }
520
        $this->messageHelperService->getPrivacyHelper()
521
            ->overwrite8bitContentEncoding($this);
522
        $this->messageHelperService->getPrivacyHelper()
523
            ->ensureHtmlPartFirstForSignedMessage($this);
524
        $this->setSignature('Not set');
525
    }
526
527
    /**
528
     * Sets the signature body of the message to the passed $body for a
529
     * multipart/signed message.
530
     *
531
     * @param string $body
532
     */
533
    public function setSignature($body)
534
    {
535
        $this->messageHelperService->getPrivacyHelper()
536
            ->setSignature($this, $body);
537
    }
538
}
539