Passed
Push — 1.0.0 ( d49389...cbb558 )
by Zaahid
03:21
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 Psr\Http\Message\StreamInterface;
10
use ZBateson\MailMimeParser\Header\HeaderFactory;
11
use ZBateson\MailMimeParser\Message\Helper\MessageHelperService;
12
use ZBateson\MailMimeParser\Message\Part\MimePart;
13
use ZBateson\MailMimeParser\Message\Part\PartBuilder;
14
use ZBateson\MailMimeParser\Message\Part\PartStreamFilterManager;
15
use ZBateson\MailMimeParser\Message\PartFilter;
16
use ZBateson\MailMimeParser\Message\PartFilterFactory;
17
use ZBateson\MailMimeParser\Stream\StreamFactory;
18
19
/**
20
 * A parsed mime message with optional mime parts depending on its type.
21
 * 
22
 * A mime message may have any number of mime parts, and each part may have any
23
 * number of sub-parts, etc...
24
 *
25
 * @author Zaahid Bateson
26
 */
27
class Message extends MimePart
28
{
29
    /**
30
     * @var MessageHelperService helper class with various message manipulation
31
     *      routines.
32
     */
33
    protected $messageHelperService;
34
35
    /**
36
     * @param PartStreamFilterManager $partStreamFilterManager
37
     * @param StreamFactory $streamFactory
38
     * @param PartFilterFactory $partFilterFactory
39
     * @param HeaderFactory $headerFactory
40
     * @param PartBuilder $partBuilder
41
     * @param MessageHelperService $messageHelperService
42
     * @param StreamInterface $stream
43
     * @param StreamInterface $contentStream
44
     */
45 10
    public function __construct(
46
        PartStreamFilterManager $partStreamFilterManager,
47
        StreamFactory $streamFactory,
48
        PartFilterFactory $partFilterFactory,
49
        HeaderFactory $headerFactory,
50
        PartBuilder $partBuilder,
51
        MessageHelperService $messageHelperService,
52
        StreamInterface $stream = null,
53
        StreamInterface $contentStream = null
54
    ) {
55 10
        parent::__construct(
56 10
            $partStreamFilterManager,
57 10
            $streamFactory,
58 10
            $partFilterFactory,
59 10
            $headerFactory,
60 10
            $partBuilder,
61 10
            $stream,
62 10
            $contentStream
63
        );
64 10
        $this->messageHelperService = $messageHelperService;
65 10
    }
66
67
    /**
68
     * Convenience method to parse a handle or string into a Message without
69
     * requiring including MailMimeParser, instantiating it, and calling parse.
70
     * 
71
     * @param resource|string $handleOrString the resource handle to the input
72
     *        stream of the mime message, or a string containing a mime message
73
     */
74
    public static function from($handleOrString)
75
    {
76
        $mmp = new MailMimeParser();
77
        return $mmp->parse($handleOrString);
78
    }
79
80
    /**
81
     * Returns the text/plain part at the given index (or null if not found.)
82
     * 
83
     * @param int $index
84
     * @return \ZBateson\MailMimeParser\Message\Part\MimePart
85
     */
86 1
    public function getTextPart($index = 0)
87
    {
88 1
        return $this->getPart(
89 1
            $index,
90 1
            $this->partFilterFactory->newFilterFromInlineContentType('text/plain')
91
        );
92
    }
93
    
94
    /**
95
     * Returns the number of text/plain parts in this message.
96
     * 
97
     * @return int
98
     */
99 1
    public function getTextPartCount()
100
    {
101 1
        return $this->getPartCount(
102 1
            $this->partFilterFactory->newFilterFromInlineContentType('text/plain')
103
        );
104
    }
105
    
106
    /**
107
     * Returns the text/html part at the given index (or null if not found.)
108
     * 
109
     * @param $index
110
     * @return \ZBateson\MailMimeParser\Message\Part\MimePart
111
     */
112 1
    public function getHtmlPart($index = 0)
113
    {
114 1
        return $this->getPart(
115 1
            $index,
116 1
            $this->partFilterFactory->newFilterFromInlineContentType('text/html')
117
        );
118
    }
119
    
120
    /**
121
     * Returns the number of text/html parts in this message.
122
     * 
123
     * @return int
124
     */
125 1
    public function getHtmlPartCount()
126
    {
127 1
        return $this->getPartCount(
128 1
            $this->partFilterFactory->newFilterFromInlineContentType('text/html')
129
        );
130
    }
131
132
    /**
133
     * Returns the attachment part at the given 0-based index, or null if none
134
     * is set.
135
     * 
136
     * @param int $index
137
     * @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...
138
     */
139 1
    public function getAttachmentPart($index)
140
    {
141 1
        $attachments = $this->getAllAttachmentParts();
142 1
        if (!isset($attachments[$index])) {
143 1
            return null;
144
        }
145 1
        return $attachments[$index];
146
    }
147
148
    /**
149
     * Returns all attachment parts.
150
     * 
151
     * "Attachments" are any non-multipart, non-signature and any text or html
152
     * html part witha Content-Disposition set to  'attachment'.
153
     * 
154
     * @return MessagePart[]
155
     */
156 1
    public function getAllAttachmentParts()
157
    {
158 1
        $parts = $this->getAllParts(
159 1
            $this->partFilterFactory->newFilterFromArray([
160 1
                'multipart' => PartFilter::FILTER_EXCLUDE
161
            ])
162
        );
163 1
        return array_values(array_filter(
164 1
            $parts,
165 1
            function ($part) {
166
                return !(
167 1
                    $part->isTextPart()
168 1
                    && $part->getContentDisposition() === 'inline'
169
                );
170 1
            }
171
        ));
172
    }
173
174
    /**
175
     * Returns the number of attachments available.
176
     * 
177
     * @return int
178
     */
179 1
    public function getAttachmentCount()
180
    {
181 1
        return count($this->getAllAttachmentParts());
182
    }
183
184
    /**
185
     * Returns a resource handle where the 'inline' text/plain content at the
186
     * passed $index can be read or null if unavailable.
187
     * 
188
     * @param int $index
189
     * @param string $charset
190
     * @return resource
191
     */
192 1
    public function getTextStream($index = 0, $charset = MailMimeParser::DEFAULT_CHARSET)
193
    {
194 1
        $textPart = $this->getTextPart($index);
195 1
        if ($textPart !== null) {
196 1
            return $textPart->getContentResourceHandle($charset);
197
        }
198 1
        return null;
199
    }
200
201
    /**
202
     * Returns the content of the inline text/plain part at the given index.
203
     * 
204
     * Reads the entire stream content into a string and returns it.  Returns
205
     * null if the message doesn't have an inline text part.
206
     * 
207
     * @param int $index
208
     * @param string $charset
209
     * @return string
210
     */
211 1
    public function getTextContent($index = 0, $charset = MailMimeParser::DEFAULT_CHARSET)
212
    {
213 1
        $part = $this->getTextPart($index);
214 1
        if ($part !== null) {
215 1
            return $part->getContent($charset);
216
        }
217 1
        return null;
218
    }
219
220
    /**
221
     * Returns a resource handle where the 'inline' text/html content at the
222
     * passed $index can be read or null if unavailable.
223
     * 
224
     * @param int $index
225
     * @param string $charset
226
     * @return resource
227
     */
228 1
    public function getHtmlStream($index = 0, $charset = MailMimeParser::DEFAULT_CHARSET)
229
    {
230 1
        $htmlPart = $this->getHtmlPart($index);
231 1
        if ($htmlPart !== null) {
232 1
            return $htmlPart->getContentResourceHandle($charset);
233
        }
234 1
        return null;
235
    }
236
237
    /**
238
     * Returns the content of the inline text/html part at the given index.
239
     * 
240
     * Reads the entire stream content into a string and returns it.  Returns
241
     * null if the message doesn't have an inline html part.
242
     * 
243
     * @param int $index
244
     * @param string $charset
245
     * @return string
246
     */
247 1
    public function getHtmlContent($index = 0, $charset = MailMimeParser::DEFAULT_CHARSET)
248
    {
249 1
        $part = $this->getHtmlPart($index);
250 1
        if ($part !== null) {
251 1
            return $part->getContent($charset);
252
        }
253 1
        return null;
254
    }
255
256
    /**
257
     * Returns true if either a Content-Type or Mime-Version header are defined
258
     * in this Message.
259
     * 
260
     * @return bool
261
     */
262 3
    public function isMime()
263
    {
264 3
        $contentType = $this->getHeaderValue('Content-Type');
265 3
        $mimeVersion = $this->getHeaderValue('Mime-Version');
266 3
        return ($contentType !== null || $mimeVersion !== null);
267
    }
268
269
    /**
270
     * Sets the text/plain part of the message to the passed $stringOrHandle,
271
     * either creating a new part if one doesn't exist for text/plain, or
272
     * assigning the value of $stringOrHandle to an existing text/plain part.
273
     *
274
     * The optional $charset parameter is the charset for saving to.
275
     * $stringOrHandle is expected to be in UTF-8 regardless of the target
276
     * charset.
277
     *
278
     * @param string|resource $stringOrHandle
279
     * @param string $charset
280
     */
281
    public function setTextPart($stringOrHandle, $charset = 'UTF-8')
282
    {
283
        $this->messageHelperService
284
            ->getMultipartHelper()
285
            ->setContentPartForMimeType(
286
                $this, 'text/plain', $stringOrHandle, $charset
287
            );
288
    }
289
290
    /**
291
     * Sets the text/html part of the message to the passed $stringOrHandle,
292
     * either creating a new part if one doesn't exist for text/html, or
293
     * assigning the value of $stringOrHandle to an existing text/html part.
294
     *
295
     * The optional $charset parameter is the charset for saving to.
296
     * $stringOrHandle is expected to be in UTF-8 regardless of the target
297
     * charset.
298
     *
299
     * @param string|resource $stringOrHandle
300
     * @param string $charset
301
     */
302
    public function setHtmlPart($stringOrHandle, $charset = 'UTF-8')
303
    {
304
        $this->messageHelperService
305
            ->getMultipartHelper()
306
            ->setContentPartForMimeType(
307
                $this, 'text/html', $stringOrHandle, $charset
308
            );
309
    }
310
311
    /**
312
     * Removes the text/plain part of the message at the passed index if one
313
     * exists.  Returns true on success.
314
     *
315
     * @return bool true on success
316
     */
317
    public function removeTextPart($index = 0)
318
    {
319
        return $this->messageHelperService
320
            ->getMultipartHelper()
321
            ->removePartByMimeType(
322
                $this, 'text/plain', $index
323
            );
324
    }
325
326
    /**
327
     * Removes all text/plain inline parts in this message, optionally keeping
328
     * other inline parts as attachments on the main message (defaults to
329
     * keeping them).
330
     *
331
     * @param bool $keepOtherPartsAsAttachments
332
     * @return bool true on success
333
     */
334
    public function removeAllTextParts($keepOtherPartsAsAttachments = true)
335
    {
336
        return $this->messageHelperService
337
            ->getMultipartHelper()
338
            ->removeAllContentPartsByMimeType(
339
                $this, 'text/plain', $keepOtherPartsAsAttachments
340
            );
341
    }
342
343
    /**
344
     * Removes the html part of the message if one exists.  Returns true on
345
     * success.
346
     *
347
     * @return bool true on success
348
     */
349
    public function removeHtmlPart($index = 0)
350
    {
351
        return $this->messageHelperService
352
            ->getMultipartHelper()
353
            ->removePartByMimeType(
354
                $this, 'text/html', $index
355
            );
356
    }
357
358
    /**
359
     * Removes all text/html inline parts in this message, optionally keeping
360
     * other inline parts as attachments on the main message (defaults to
361
     * keeping them).
362
     *
363
     * @param bool $keepOtherPartsAsAttachments
364
     * @return bool true on success
365
     */
366
    public function removeAllHtmlParts($keepOtherPartsAsAttachments = true)
367
    {
368
        return $this->messageHelperService
369
            ->getMultipartHelper()
370
            ->removeAllContentPartsByMimeType(
371
                $this, 'text/html', $keepOtherPartsAsAttachments
372
            );
373
    }
374
375
    /**
376
     * Removes the attachment with the given index
377
     *
378
     * @param int $index
379
     */
380
    public function removeAttachmentPart($index)
381
    {
382
        $part = $this->getAttachmentPart($index);
383
        $this->removePart($part);
384
    }
385
386
    /**
387
     * Adds an attachment part for the passed raw data string or handle and
388
     * given parameters.
389
     *
390
     * @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...
391
     * @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...
392
     * @param string $filename
393
     * @param string $disposition
394
     */
395
    public function addAttachmentPart($stringOrHandle, $mimeType, $filename = null, $disposition = 'attachment')
396
    {
397
        if ($filename === null) {
398
            $filename = 'file' . uniqid();
399
        }
400
        $part = $this->messageHelperService
401
            ->getMultipartHelper()
402
            ->createPartForAttachment($this, $mimeType, $filename, $disposition);
403
        $part->setContent($stringOrHandle);
404
        $this->addChild($part);
405
    }
406
407
    /**
408
     * Adds an attachment part using the passed file.
409
     *
410
     * Essentially creates a file stream and uses it.
411
     *
412
     * @param string $file
413
     * @param string $mimeType
414
     * @param string $filename
415
     * @param string $disposition
416
     */
417
    public function addAttachmentPartFromFile($file, $mimeType, $filename = null, $disposition = 'attachment')
418
    {
419
        $handle = fopen($file, 'r');
420
        if ($filename === null) {
421
            $filename = basename($file);
422
        }
423
        $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

423
        $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

423
        $this->addAttachmentPart($handle, /** @scrutinizer ignore-type */ $mimeType, $filename, $disposition);
Loading history...
424
    }
425
426
    /**
427
     * Returns a string containing the entire body of a signed message for
428
     * verification or calculating a signature.
429
     *
430
     * @return string or null if the message doesn't have any children, or the
431
     *      child returns null for getHandle
432
     */
433 2
    public function getSignedMessageAsString()
434
    {
435 2
        $child = $this->getChild(0);
436 2
        if ($child !== null) {
437 1
            $normalized = preg_replace(
438 1
                '/\r\n|\r|\n/',
439 1
                "\r\n",
440 1
                $child->getStream()->getContents()
441
            );
442 1
            return $normalized;
443
        }
444 1
        return null;
445
    }
446
447
    /**
448
     * Returns the signature part of a multipart/signed message or null.
449
     *
450
     * The signature part is determined to always be the 2nd child of a
451
     * multipart/signed message, the first being the 'body'.
452
     *
453
     * Using the 'protocol' parameter of the Content-Type header is unreliable
454
     * in some instances (for instance a difference of x-pgp-signature versus
455
     * pgp-signature).
456
     *
457
     * @return MimePart
458
     */
459
    public function getSignaturePart()
460
    {
461
        $contentType = $this->getHeaderValue('Content-Type', 'text/plain');
462
        if (strcasecmp($contentType, 'multipart/signed') === 0) {
463
            return $this->getChild(1);
464
        } else {
465
            return null;
466
        }
467
    }
468
469
    /**
470
     * Turns the message into a multipart/signed message, moving the actual
471
     * message into a child part, sets the content-type of the main message to
472
     * multipart/signed and adds an empty signature part as well.
473
     *
474
     * After calling setAsMultipartSigned, call get
475
     *
476
     * @param string $micalg The Message Integrity Check algorithm being used
477
     * @param string $protocol The mime-type of the signature body
478
     */
479
    public function setAsMultipartSigned($micalg, $protocol)
480
    {
481
        $contentType = $this->getHeaderValue('Content-Type', 'text/plain');
482
        if (strcasecmp($contentType, 'multipart/signed') !== 0) {
483
            $this->messageHelperService->getPrivacyHelper()
484
                ->setMessageAsMultipartSigned($this, $micalg, $protocol);
485
        }
486
        $this->messageHelperService->getPrivacyHelper()
487
            ->overwrite8bitContentEncoding($this);
488
        $this->messageHelperService->getPrivacyHelper()
489
            ->ensureHtmlPartFirstForSignedMessage($this);
490
        $this->setSignature('Not set');
491
    }
492
493
    /**
494
     * Sets the signature body of the message to the passed $body for a
495
     * multipart/signed message.
496
     *
497
     * @param string $body
498
     */
499
    public function setSignature($body)
500
    {
501
        $this->messageHelperService->getPrivacyHelper()
502
            ->setSignature($this, $body);
503
    }
504
}
505