Passed
Push — master ( 663ed6...20cd88 )
by Zaahid
03:54
created

Message::getSubject()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 0
crap 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 Psr\Log\LoggerInterface;
13
use ZBateson\MailMimeParser\Header\HeaderConsts;
14
use ZBateson\MailMimeParser\Message\Helper\MultipartHelper;
15
use ZBateson\MailMimeParser\Message\Helper\PrivacyHelper;
16
use ZBateson\MailMimeParser\Message\IMessagePart;
17
use ZBateson\MailMimeParser\Message\MimePart;
18
use ZBateson\MailMimeParser\Message\PartChildrenContainer;
19
use ZBateson\MailMimeParser\Message\PartFilter;
20
use ZBateson\MailMimeParser\Message\PartHeaderContainer;
21
use ZBateson\MailMimeParser\Message\PartStreamContainer;
22
23
/**
24
 * An email message.
25
 *
26
 * The message could represent a simple text email, a multipart message with
27
 * children, or a non-mime message containing UUEncoded parts.
28
 *
29
 * @author Zaahid Bateson
30
 */
31
class Message extends MimePart implements IMessage
32
{
33
    /**
34
     * @var MultipartHelper service providing functions for multipart messages.
35
     */
36
    private MultipartHelper $multipartHelper;
37
38
    /**
39
     * @var PrivacyHelper service providing functions for multipart/signed
40
     *      messages.
41
     */
42
    private PrivacyHelper $privacyHelper;
43
44 119
    public function __construct(
45
        ?LoggerInterface $logger = null,
46
        ?PartStreamContainer $streamContainer = null,
47
        ?PartHeaderContainer $headerContainer = null,
48
        ?PartChildrenContainer $partChildrenContainer = null,
49
        ?MultipartHelper $multipartHelper = null,
50
        ?PrivacyHelper $privacyHelper = null
51
    ) {
52 119
        parent::__construct(
53 119
            null,
54 119
            $logger,
55 119
            $streamContainer,
56 119
            $headerContainer,
57 119
            $partChildrenContainer
58 119
        );
59 119
        $di = MailMimeParser::getGlobalContainer();
60 119
        $this->multipartHelper = $multipartHelper ?? $di->get(MultipartHelper::class);
61 119
        $this->privacyHelper = $privacyHelper ?? $di->get(PrivacyHelper::class);
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
     */
81 1
    public static function from(mixed $resource, bool $attached) : IMessage
82
    {
83 1
        static $mmp = null;
84 1
        if ($mmp === null) {
85 1
            $mmp = new MailMimeParser();
86
        }
87 1
        return $mmp->parse($resource, $attached);
88
    }
89
90
    /**
91
     * Returns true if the current part is a mime part.
92
     *
93
     * The message is considered 'mime' if it has either a Content-Type or
94
     * MIME-Version header defined.
95
     *
96
     */
97 20
    public function isMime() : bool
98
    {
99 20
        $contentType = $this->getHeaderValue(HeaderConsts::CONTENT_TYPE);
100 20
        $mimeVersion = $this->getHeaderValue(HeaderConsts::MIME_VERSION);
101 20
        return ($contentType !== null || $mimeVersion !== null);
102
    }
103
104 95
    public function getSubject() : ?string
105
    {
106 95
        return $this->getHeaderValue(HeaderConsts::SUBJECT);
107
    }
108
109 74
    public function getTextPart(int $index = 0) : ?IMessagePart
110
    {
111 74
        return $this->getPart(
112 74
            $index,
113 74
            PartFilter::fromInlineContentType('text/plain')
114 74
        );
115
    }
116
117 1
    public function getTextPartCount() : int
118
    {
119 1
        return $this->getPartCount(
120 1
            PartFilter::fromInlineContentType('text/plain')
121 1
        );
122
    }
123
124 36
    public function getHtmlPart(int $index = 0) : ?IMessagePart
125
    {
126 36
        return $this->getPart(
127 36
            $index,
128 36
            PartFilter::fromInlineContentType('text/html')
129 36
        );
130
    }
131
132 1
    public function getHtmlPartCount() : int
133
    {
134 1
        return $this->getPartCount(
135 1
            PartFilter::fromInlineContentType('text/html')
136 1
        );
137
    }
138
139 70
    public function getTextStream(int $index = 0, string $charset = MailMimeParser::DEFAULT_CHARSET) : ?StreamInterface
140
    {
141 70
        $textPart = $this->getTextPart($index);
142 70
        if ($textPart !== null) {
143 70
            return $textPart->getContentStream($charset);
144
        }
145 1
        return null;
146
    }
147
148 2
    public function getTextContent(int $index = 0, string $charset = MailMimeParser::DEFAULT_CHARSET) : ?string
149
    {
150 2
        $part = $this->getTextPart($index);
151 2
        if ($part !== null) {
152 2
            return $part->getContent($charset);
153
        }
154 1
        return null;
155
    }
156
157 30
    public function getHtmlStream(int $index = 0, string $charset = MailMimeParser::DEFAULT_CHARSET) : ?StreamInterface
158
    {
159 30
        $htmlPart = $this->getHtmlPart($index);
160 30
        if ($htmlPart !== null) {
161 30
            return $htmlPart->getContentStream($charset);
162
        }
163 1
        return null;
164
    }
165
166 2
    public function getHtmlContent(int $index = 0, string $charset = MailMimeParser::DEFAULT_CHARSET) : ?string
167
    {
168 2
        $part = $this->getHtmlPart($index);
169 2
        if ($part !== null) {
170 2
            return $part->getContent($charset);
171
        }
172 1
        return null;
173
    }
174
175 2
    public function setTextPart(mixed $resource, string $charset = 'UTF-8') : static
176
    {
177 2
        $this->multipartHelper
178 2
            ->setContentPartForMimeType(
179 2
                $this,
180 2
                'text/plain',
181 2
                $resource,
182 2
                $charset
183 2
            );
184 2
        return $this;
185
    }
186
187 5
    public function setHtmlPart(mixed $resource, string $charset = 'UTF-8') : static
188
    {
189 5
        $this->multipartHelper
190 5
            ->setContentPartForMimeType(
191 5
                $this,
192 5
                'text/html',
193 5
                $resource,
194 5
                $charset
195 5
            );
196 5
        return $this;
197
    }
198
199 4
    public function removeTextPart(int $index = 0) : bool
200
    {
201 4
        return $this->multipartHelper
202 4
            ->removePartByMimeType(
203 4
                $this,
204 4
                'text/plain',
205 4
                $index
206 4
            );
207
    }
208
209 1
    public function removeAllTextParts(bool $moveRelatedPartsBelowMessage = true) : bool
210
    {
211 1
        return $this->multipartHelper
212 1
            ->removeAllContentPartsByMimeType(
213 1
                $this,
214 1
                'text/plain',
215 1
                $moveRelatedPartsBelowMessage
216 1
            );
217
    }
218
219 3
    public function removeHtmlPart(int $index = 0) : bool
220
    {
221 3
        return $this->multipartHelper
222 3
            ->removePartByMimeType(
223 3
                $this,
224 3
                'text/html',
225 3
                $index
226 3
            );
227
    }
228
229 2
    public function removeAllHtmlParts(bool $moveRelatedPartsBelowMessage = true) : bool
230
    {
231 2
        return $this->multipartHelper
232 2
            ->removeAllContentPartsByMimeType(
233 2
                $this,
234 2
                'text/html',
235 2
                $moveRelatedPartsBelowMessage
236 2
            );
237
    }
238
239 5
    public function getAttachmentPart(int $index) : ?IMessagePart
240
    {
241 5
        return $this->getPart(
242 5
            $index,
243 5
            PartFilter::fromAttachmentFilter()
244 5
        );
245
    }
246
247 57
    public function getAllAttachmentParts() : array
248
    {
249 57
        return $this->getAllParts(
250 57
            PartFilter::fromAttachmentFilter()
251 57
        );
252
    }
253
254 57
    public function getAttachmentCount() : int
255
    {
256 57
        return \count($this->getAllAttachmentParts());
257
    }
258
259 5
    public function addAttachmentPart(mixed $resource, string $mimeType, ?string $filename = null, string $disposition = 'attachment', string $encoding = 'base64') : static
260
    {
261 5
        $this->multipartHelper
262 5
            ->createAndAddPartForAttachment(
263 5
                $this,
264 5
                $resource,
265 5
                $mimeType,
266 5
                (\strcasecmp($disposition, 'inline') === 0) ? 'inline' : 'attachment',
267 5
                $filename,
268 5
                $encoding
269 5
            );
270 5
        return $this;
271
    }
272
273 5
    public function addAttachmentPartFromFile(string $filePath, string $mimeType, ?string $filename = null, string $disposition = 'attachment', string $encoding = 'base64') : static
274
    {
275 5
        $handle = Psr7\Utils::streamFor(\fopen($filePath, 'r'));
276 5
        if ($filename === null) {
277 4
            $filename = \basename($filePath);
278
        }
279 5
        $this->addAttachmentPart($handle, $mimeType, $filename, $disposition, $encoding);
280 5
        return $this;
281
    }
282
283 3
    public function removeAttachmentPart(int $index) : static
284
    {
285 3
        $part = $this->getAttachmentPart($index);
286 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

286
        $this->removePart(/** @scrutinizer ignore-type */ $part);
Loading history...
287 3
        return $this;
288
    }
289
290 1
    public function getSignedMessageStream() : ?StreamInterface
291
    {
292 1
        return $this
293 1
            ->privacyHelper
294 1
            ->getSignedMessageStream($this);
295
    }
296
297 15
    public function getSignedMessageAsString() : ?string
298
    {
299 15
        return $this
300 15
            ->privacyHelper
301 15
            ->getSignedMessageAsString($this);
302
    }
303
304 62
    public function getSignaturePart() : ?IMessagePart
305
    {
306 62
        if (\strcasecmp($this->getContentType(), 'multipart/signed') === 0) {
307 19
            return $this->getChild(1);
308
        }
309 43
        return null;
310
    }
311
312 10
    public function setAsMultipartSigned(string $micalg, string $protocol) : static
313
    {
314 10
        $this->privacyHelper
315 10
            ->setMessageAsMultipartSigned($this, $micalg, $protocol);
316 10
        return $this;
317
    }
318
319 10
    public function setSignature(string $body) : static
320
    {
321 10
        $this->privacyHelper
322 10
            ->setSignature($this, $body);
323 10
        return $this;
324
    }
325
326 73
    public function getMessageId() : ?string
327
    {
328 73
        return $this->getHeaderValue(HeaderConsts::MESSAGE_ID);
329
    }
330
331 73
    public function getErrorLoggingContextName() : string
332
    {
333 73
        $params = '';
334 73
        if (!empty($this->getMessageId())) {
335 73
            $params .= ', message-id=' . $this->getContentId();
336
        }
337 73
        $params .= ', content-type=' . $this->getContentType();
338 73
        $nsClass = static::class;
339 73
        $class = \substr($nsClass, (\strrpos($nsClass, '\\') ?? -1) + 1);
340 73
        return $class . '(' . \spl_object_id($this) . $params . ')';
341
    }
342
}
343