Passed
Push — master ( 181d77...7fe46a )
by Zaahid
06:13 queued 12s
created

Message   A

Complexity

Total Complexity 39

Size/Duplication

Total Lines 304
Duplicated Lines 0 %

Test Coverage

Coverage 98.1%

Importance

Changes 9
Bugs 1 Features 0
Metric Value
wmc 39
eloc 119
c 9
b 1
f 0
dl 0
loc 304
ccs 155
cts 158
cp 0.981
rs 9.28

28 Methods

Rating   Name   Duplication   Size   Complexity  
A isMime() 0 5 2
A getHtmlPartCount() 0 4 1
A getTextPartCount() 0 4 1
A getHtmlStream() 0 7 2
A getTextPart() 0 5 1
A getHtmlContent() 0 7 2
A getHtmlPart() 0 5 1
A getTextStream() 0 7 2
A getTextContent() 0 7 2
A __construct() 0 20 3
A from() 0 7 2
A removeAllTextParts() 0 7 1
A getAllAttachmentParts() 0 4 1
A removeAllHtmlParts() 0 7 1
A getAttachmentPart() 0 5 1
A addAttachmentPart() 0 12 2
A setTextPart() 0 10 1
A addAttachmentPartFromFile() 0 8 2
A removeTextPart() 0 7 1
A setAsMultipartSigned() 0 5 1
A setHtmlPart() 0 10 1
A getSignaturePart() 0 6 2
A getSignedMessageAsString() 0 5 1
A setSignature() 0 5 1
A removeHtmlPart() 0 7 1
A getSignedMessageStream() 0 5 1
A getAttachmentCount() 0 3 1
A removeAttachmentPart() 0 5 1
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;
9
10
use GuzzleHttp\Psr7;
11
use Psr\Http\Message\StreamInterface;
12
use ZBateson\MailMimeParser\Header\HeaderConsts;
13
use ZBateson\MailMimeParser\Message\Helper\MultipartHelper;
14
use ZBateson\MailMimeParser\Message\Helper\PrivacyHelper;
15
use ZBateson\MailMimeParser\Message\MimePart;
16
use ZBateson\MailMimeParser\Message\PartChildrenContainer;
17
use ZBateson\MailMimeParser\Message\PartFilter;
18
use ZBateson\MailMimeParser\Message\PartHeaderContainer;
19
use ZBateson\MailMimeParser\Message\PartStreamContainer;
20
21
/**
22
 * An email message.
23
 *
24
 * The message could represent a simple text email, a multipart message with
25
 * children, or a non-mime message containing UUEncoded parts.
26
 *
27
 * @author Zaahid Bateson
28
 */
29
class Message extends MimePart implements IMessage
30
{
31
    /**
32
     * @var MultipartHelper service providing functions for multipart messages.
33
     */
34
    private $multipartHelper;
35
36
    /**
37
     * @var PrivacyHelper service providing functions for multipart/signed
38
     *      messages.
39
     */
40
    private $privacyHelper;
41
42 116
    public function __construct(
43
        ?PartStreamContainer $streamContainer = null,
44
        ?PartHeaderContainer $headerContainer = null,
45
        ?PartChildrenContainer $partChildrenContainer = null,
46
        ?MultipartHelper $multipartHelper = null,
47
        ?PrivacyHelper $privacyHelper = null
48
    ) {
49 116
        parent::__construct(
50 116
            null,
51 116
            $streamContainer,
52 116
            $headerContainer,
53 116
            $partChildrenContainer
54 116
        );
55 116
        if ($multipartHelper === null || $privacyHelper === null) {
56
            $di = MailMimeParser::getDependencyContainer();
57
            $multipartHelper = $di[\ZBateson\MailMimeParser\Message\Helper\MultipartHelper::class];
58
            $privacyHelper = $di[\ZBateson\MailMimeParser\Message\Helper\PrivacyHelper::class];
59
        }
60 116
        $this->multipartHelper = $multipartHelper;
61 116
        $this->privacyHelper = $privacyHelper;
62
    }
63
64
    /**
65
     * Convenience method to parse a handle or string into an IMessage without
66
     * requiring including MailMimeParser, instantiating it, and calling parse.
67
     *
68
     * If the passed $resource is a resource handle or StreamInterface, the
69
     * resource must remain open while the returned IMessage object exists.
70
     * Pass true as the second argument to have the resource attached to the
71
     * IMessage and closed for you when it's destroyed, or pass false to
72
     * manually close it if it should remain open after the IMessage object is
73
     * destroyed.
74
     *
75
     * @param resource|StreamInterface|string $resource The resource handle to
76
     *        the input stream of the mime message, or a string containing a
77
     *        mime message.
78
     * @param bool $attached pass true to have it attached to the returned
79
     *        IMessage and destroyed with it.
80
     * @return IMessage
81
     */
82 1
    public static function from($resource, $attached)
83
    {
84 1
        static $mmp = null;
85 1
        if ($mmp === null) {
86 1
            $mmp = new MailMimeParser();
87
        }
88 1
        return $mmp->parse($resource, $attached);
89
    }
90
91
    /**
92
     * Returns true if the current part is a mime part.
93
     *
94
     * The message is considered 'mime' if it has either a Content-Type or
95
     * MIME-Version header defined.
96
     *
97
     */
98 19
    public function isMime() : bool
99
    {
100 19
        $contentType = $this->getHeaderValue(HeaderConsts::CONTENT_TYPE);
101 19
        $mimeVersion = $this->getHeaderValue(HeaderConsts::MIME_VERSION);
102 19
        return ($contentType !== null || $mimeVersion !== null);
103
    }
104
105 72
    public function getTextPart($index = 0)
106
    {
107 72
        return $this->getPart(
108 72
            $index,
109 72
            PartFilter::fromInlineContentType('text/plain')
110 72
        );
111
    }
112
113 1
    public function getTextPartCount()
114
    {
115 1
        return $this->getPartCount(
116 1
            PartFilter::fromInlineContentType('text/plain')
117 1
        );
118
    }
119
120 36
    public function getHtmlPart($index = 0)
121
    {
122 36
        return $this->getPart(
123 36
            $index,
124 36
            PartFilter::fromInlineContentType('text/html')
125 36
        );
126
    }
127
128 1
    public function getHtmlPartCount()
129
    {
130 1
        return $this->getPartCount(
131 1
            PartFilter::fromInlineContentType('text/html')
132 1
        );
133
    }
134
135 68
    public function getTextStream($index = 0, $charset = MailMimeParser::DEFAULT_CHARSET)
136
    {
137 68
        $textPart = $this->getTextPart($index);
138 68
        if ($textPart !== null) {
139 68
            return $textPart->getContentStream($charset);
140
        }
141 1
        return null;
142
    }
143
144 2
    public function getTextContent($index = 0, $charset = MailMimeParser::DEFAULT_CHARSET)
145
    {
146 2
        $part = $this->getTextPart($index);
147 2
        if ($part !== null) {
148 2
            return $part->getContent($charset);
149
        }
150 1
        return null;
151
    }
152
153 30
    public function getHtmlStream($index = 0, $charset = MailMimeParser::DEFAULT_CHARSET)
154
    {
155 30
        $htmlPart = $this->getHtmlPart($index);
156 30
        if ($htmlPart !== null) {
157 30
            return $htmlPart->getContentStream($charset);
158
        }
159 1
        return null;
160
    }
161
162 2
    public function getHtmlContent($index = 0, $charset = MailMimeParser::DEFAULT_CHARSET)
163
    {
164 2
        $part = $this->getHtmlPart($index);
165 2
        if ($part !== null) {
166 2
            return $part->getContent($charset);
167
        }
168 1
        return null;
169
    }
170
171
    /**
172
     * @return static
173
     */
174 2
    public function setTextPart($resource, string $charset = 'UTF-8')
175
    {
176 2
        $this->multipartHelper
177 2
            ->setContentPartForMimeType(
178 2
                $this,
179 2
                'text/plain',
180 2
                $resource,
181 2
                $charset
182 2
            );
183 2
        return $this;
184
    }
185
186 5
    public function setHtmlPart($resource, string $charset = 'UTF-8') : self
187
    {
188 5
        $this->multipartHelper
189 5
            ->setContentPartForMimeType(
190 5
                $this,
191 5
                'text/html',
192 5
                $resource,
193 5
                $charset
194 5
            );
195 5
        return $this;
196
    }
197
198 4
    public function removeTextPart(int $index = 0) : bool
199
    {
200 4
        return $this->multipartHelper
201 4
            ->removePartByMimeType(
202 4
                $this,
203 4
                'text/plain',
204 4
                $index
205 4
            );
206
    }
207
208 1
    public function removeAllTextParts(bool $moveRelatedPartsBelowMessage = true) : bool
209
    {
210 1
        return $this->multipartHelper
211 1
            ->removeAllContentPartsByMimeType(
212 1
                $this,
213 1
                'text/plain',
214 1
                $moveRelatedPartsBelowMessage
215 1
            );
216
    }
217
218 3
    public function removeHtmlPart(int $index = 0) : bool
219
    {
220 3
        return $this->multipartHelper
221 3
            ->removePartByMimeType(
222 3
                $this,
223 3
                'text/html',
224 3
                $index
225 3
            );
226
    }
227
228 2
    public function removeAllHtmlParts(bool $moveRelatedPartsBelowMessage = true) : bool
229
    {
230 2
        return $this->multipartHelper
231 2
            ->removeAllContentPartsByMimeType(
232 2
                $this,
233 2
                'text/html',
234 2
                $moveRelatedPartsBelowMessage
235 2
            );
236
    }
237
238 5
    public function getAttachmentPart(int $index)
239
    {
240 5
        return $this->getPart(
241 5
            $index,
242 5
            PartFilter::fromAttachmentFilter()
243 5
        );
244
    }
245
246 57
    public function getAllAttachmentParts()
247
    {
248 57
        return $this->getAllParts(
249 57
            PartFilter::fromAttachmentFilter()
250 57
        );
251
    }
252
253 57
    public function getAttachmentCount() : int
254
    {
255 57
        return \count($this->getAllAttachmentParts());
256
    }
257
258
    /**
259
     * @return static
260
     */
261 5
    public function addAttachmentPart($resource, string $mimeType, ?string $filename = null, string $disposition = 'attachment', string $encoding = 'base64')
262
    {
263 5
        $this->multipartHelper
264 5
            ->createAndAddPartForAttachment(
265 5
                $this,
266 5
                $resource,
267 5
                $mimeType,
268 5
                (\strcasecmp($disposition, 'inline') === 0) ? 'inline' : 'attachment',
269 5
                $filename,
270 5
                $encoding
271 5
            );
272 5
        return $this;
273
    }
274
275
    /**
276
     * @return static
277
     */
278 5
    public function addAttachmentPartFromFile($filePath, string $mimeType, ?string $filename = null, string $disposition = 'attachment', string $encoding = 'base64')
279
    {
280 5
        $handle = Psr7\Utils::streamFor(\fopen($filePath, 'r'));
281 5
        if ($filename === null) {
282 4
            $filename = \basename($filePath);
283
        }
284 5
        $this->addAttachmentPart($handle, $mimeType, $filename, $disposition, $encoding);
285 5
        return $this;
286
    }
287
288 3
    public function removeAttachmentPart(int $index) : self
289
    {
290 3
        $part = $this->getAttachmentPart($index);
291 3
        $this->removePart($part);
0 ignored issues
show
Bug introduced by
It seems like $part can also be of type null; however, parameter $part of ZBateson\MailMimeParser\...MultiPart::removePart() does only seem to accept ZBateson\MailMimeParser\Message\IMessagePart, maybe add an additional type check? ( Ignorable by Annotation )

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

291
        $this->removePart(/** @scrutinizer ignore-type */ $part);
Loading history...
292 3
        return $this;
293
    }
294
295 1
    public function getSignedMessageStream()
296
    {
297 1
        return $this
298 1
            ->privacyHelper
299 1
            ->getSignedMessageStream($this);
300
    }
301
302 14
    public function getSignedMessageAsString()
303
    {
304 14
        return $this
305 14
            ->privacyHelper
306 14
            ->getSignedMessageAsString($this);
307
    }
308
309 61
    public function getSignaturePart()
310
    {
311 61
        if (\strcasecmp($this->getContentType(), 'multipart/signed') === 0) {
312 18
            return $this->getChild(1);
313
        }
314 43
            return null;
315
316
    }
0 ignored issues
show
Coding Style introduced by
Function closing brace must go on the next line following the body; found 1 blank lines before brace
Loading history...
317
318
    /**
319
     * @return static
320
     */
321 9
    public function setAsMultipartSigned(string $micalg, string $protocol)
322
    {
323 9
        $this->privacyHelper
324 9
            ->setMessageAsMultipartSigned($this, $micalg, $protocol);
325 9
        return $this;
326
    }
327
328 9
    public function setSignature(string $body) : self
329
    {
330 9
        $this->privacyHelper
331 9
            ->setSignature($this, $body);
332 9
        return $this;
333
    }
334
}
335