Passed
Branch 1.0.0 (a1adee)
by Zaahid
08:34
created

Message::from()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 0
cts 3
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
crap 2
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 ZBateson\MailMimeParser\Message\Part\MimePart;
10
use ZBateson\MailMimeParser\Message\PartFilter;
11
12
/**
13
 * A parsed mime message with optional mime parts depending on its type.
14
 * 
15
 * A mime message may have any number of mime parts, and each part may have any
16
 * number of sub-parts, etc...
17
 *
18
 * @author Zaahid Bateson
19
 */
20
class Message extends MimePart
21
{
22
    /**
23
     * Convenience method to parse a handle or string into a Message without
24
     * requiring including MailMimeParser, instantiating it, and calling parse.
25
     * 
26
     * @param resource|string $handleOrString the resource handle to the input
27
     *        stream of the mime message, or a string containing a mime message
28
     */
29
    public static function from($handleOrString)
30
    {
31
        $mmp = new MailMimeParser();
32
        return $mmp->parse($handleOrString);
33
    }
34
35
    /**
36
     * Returns the text/plain part at the given index (or null if not found.)
37
     * 
38
     * @param int $index
39
     * @return \ZBateson\MailMimeParser\Message\Part\MimePart
40
     */
41 1
    public function getTextPart($index = 0)
42
    {
43 1
        return $this->getPart(
44 1
            $index,
45 1
            $this->partFilterFactory->newFilterFromInlineContentType('text/plain')
46 1
        );
47
    }
48
    
49
    /**
50
     * Returns the number of text/plain parts in this message.
51
     * 
52
     * @return int
53
     */
54 1
    public function getTextPartCount()
55
    {
56 1
        return $this->getPartCount(
57 1
            $this->partFilterFactory->newFilterFromInlineContentType('text/plain')
58 1
        );
59
    }
60
    
61
    /**
62
     * Returns the text/html part at the given index (or null if not found.)
63
     * 
64
     * @param $index
65
     * @return \ZBateson\MailMimeParser\Message\Part\MimePart
66
     */
67 1
    public function getHtmlPart($index = 0)
68
    {
69 1
        return $this->getPart(
70 1
            $index,
71 1
            $this->partFilterFactory->newFilterFromInlineContentType('text/html')
72 1
        );
73
    }
74
    
75
    /**
76
     * Returns the number of text/html parts in this message.
77
     * 
78
     * @return int
79
     */
80 1
    public function getHtmlPartCount()
81
    {
82 1
        return $this->getPartCount(
83 1
            $this->partFilterFactory->newFilterFromInlineContentType('text/html')
84 1
        );
85
    }
86
87
    /**
88
     * Returns a string containing the entire body of a signed message for
89
     * verification.
90
     * 
91
     * @return string or null if the message doesn't have any children, or the
92
     *      child returns null for getHandle
93
     */
94 2
    public function getMessageStringForSignatureVerification()
95
    {
96 2
        $child = $this->getChild(0);
97 2
        if ($child !== null && $child->getHandle() !== null) {
98 1
            $normalized = preg_replace(
99 1
                '/\r\n|\r|\n/',
100 1
                "\r\n",
101 1
                stream_get_contents($child->getHandle())
102 1
            );
103 1
            return $normalized;
104
        }
105 1
        return null;
106
    }
107
    
108
    /**
109
     * Returns the signature part of a multipart/signed message.
110
     * 
111
     * The part returned is the part containing a Content-Type matching the one
112
     * defined in the multipart/signed part's "protocol" parameter.
113
     * 
114
     * @return MimePart
115
     */
116
    public function getSignaturePart()
117
    {
118
        return $this->getChild(
119
            0,
120
            $this->partFilterFactory->newFilterFromArray([
121
                'signedpart' => PartFilter::FILTER_INCLUDE
122
            ])
123
        );
124
    }
125
126
    /**
127
     * Returns the attachment part at the given 0-based index, or null if none
128
     * is set.
129
     * 
130
     * @param int $index
131
     * @return MessagePart
132
     */
133 1
    public function getAttachmentPart($index)
134
    {
135 1
        $attachments = $this->getAllAttachmentParts();
136 1
        if (!isset($attachments[$index])) {
137 1
            return null;
138
        }
139 1
        return $attachments[$index];
140
    }
141
142
    /**
143
     * Returns all attachment parts.
144
     * 
145
     * "Attachments" are any non-multipart, non-signature and any text or html
146
     * html part witha Content-Disposition set to  'attachment'.
147
     * 
148
     * @return MessagePart[]
149
     */
150 1
    public function getAllAttachmentParts()
151
    {
152 1
        $parts = $this->getAllParts(
153 1
            $this->partFilterFactory->newFilterFromArray([
154
                'multipart' => PartFilter::FILTER_EXCLUDE
155 1
            ])
156 1
        );
157 1
        return array_values(array_filter(
158 1
            $parts,
159 1
            function ($part) {
160
                return !(
161 1
                    $part->isTextPart()
162 1
                    && $part->getContentDisposition() === 'inline'
163 1
                );
164
            }
165 1
        ));
166
    }
167
168
    /**
169
     * Returns the number of attachments available.
170
     * 
171
     * @return int
172
     */
173 1
    public function getAttachmentCount()
174
    {
175 1
        return count($this->getAllAttachmentParts());
176
    }
177
178
    /**
179
     * Returns a resource handle where the 'inline' text/plain content at the
180
     * passed $index can be read or null if unavailable.
181
     * 
182
     * @param int $index
183
     * @param string $transferEncoding
184
     * @param string $charset
185
     * @return resource
186
     */
187 1
    public function getTextStream($index = 0, $transferEncoding = null, $charset = null)
188
    {
189 1
        $textPart = $this->getTextPart($index);
190 1
        if ($textPart !== null) {
191 1
            return $textPart->getContentResourceHandle($transferEncoding, $charset);
192
        }
193 1
        return null;
194
    }
195
196
    /**
197
     * Returns the content of the inline text/plain part at the given index.
198
     * 
199
     * Reads the entire stream content into a string and returns it.  Returns
200
     * null if the message doesn't have an inline text part.
201
     * 
202
     * @param int $index
203
     * @param string $transferEncoding
204
     * @param string $charset
205
     * @return string
206
     */
207 1 View Code Duplication
    public function getTextContent($index = 0, $transferEncoding = null, $charset = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
208
    {
209 1
        $part = $this->getTextPart($index);
210 1
        if ($part !== null) {
211 1
            return $part->getContent($transferEncoding, $charset);
212
        }
213 1
        return null;
214
    }
215
216
    /**
217
     * Returns a resource handle where the 'inline' text/html content at the
218
     * passed $index can be read or null if unavailable.
219
     * 
220
     * @param int $index
221
     * @param string $transferEncoding
222
     * @param string $charset
223
     * @return resource
224
     */
225 1 View Code Duplication
    public function getHtmlStream($index = 0, $transferEncoding = null, $charset = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
226
    {
227 1
        $htmlPart = $this->getHtmlPart($index);
228 1
        if ($htmlPart !== null) {
229 1
            return $htmlPart->getContentResourceHandle($transferEncoding, $charset);
230
        }
231 1
        return null;
232
    }
233
234
    /**
235
     * Returns the content of the inline text/html part at the given index.
236
     * 
237
     * Reads the entire stream content into a string and returns it.  Returns
238
     * null if the message doesn't have an inline html part.
239
     * 
240
     * @param int $index
241
     * @param string $transferEncoding
242
     * @param string $charset
243
     * @return string
244
     */
245 1 View Code Duplication
    public function getHtmlContent($index = 0, $transferEncoding = null, $charset = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
246
    {
247 1
        $part = $this->getHtmlPart($index);
248 1
        if ($part !== null) {
249 1
            return $part->getContent($transferEncoding, $charset);
250
        }
251 1
        return null;
252
    }
253
254
    /**
255
     * Returns true if either a Content-Type or Mime-Version header are defined
256
     * in this Message.
257
     * 
258
     * @return bool
259
     */
260 3
    public function isMime()
261
    {
262 3
        $contentType = $this->getHeaderValue('Content-Type');
263 3
        $mimeVersion = $this->getHeaderValue('Mime-Version');
264 3
        return ($contentType !== null || $mimeVersion !== null);
265
    }
266
267
    /**
268
     * Saves the message as a MIME message to the passed resource handle.
269
     * 
270
     * @param resource $handle
271
     */
272 1
    public function save($handle)
273
    {
274 1
        if (is_resource($this->handle)) {
275 1
            rewind($this->handle);
276 1
            stream_copy_to_stream($this->handle, $handle);
277 1
        }
278 1
    }
279
280
    /**
281
     * Shortcut to call Message::save with a php://temp stream and return the
282
     * written email message as a string.
283
     * 
284
     * @return string
285
     */
286 1
    public function __toString()
287
    {
288 1
        $handle = fopen('php://temp', 'r+');
289 1
        $this->save($handle);
290 1
        rewind($handle);
291 1
        $str = stream_get_contents($handle);
292 1
        fclose($handle);
293 1
        return $str;
294
    }
295
}
296