Passed
Push — 1.0.0 ( 4505d9...06b3ad )
by Zaahid
04:10
created

MessagePart::getContentStream()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 3
nop 1
dl 0
loc 12
ccs 9
cts 9
cp 1
crap 3
rs 9.4285
c 0
b 0
f 0
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\Message\Part;
8
9
use Psr\Http\Message\StreamInterface;
10
use ZBateson\MailMimeParser\MailMimeParser;
11
use GuzzleHttp\Psr7\StreamWrapper;
12
13
/**
14
 * Represents a single part of a message.
15
 *
16
 * A MessagePart object may have any number of child parts, or may be a child
17
 * itself with its own parent or parents.
18
 *
19
 * @author Zaahid Bateson
20
 */
21
abstract class MessagePart
22
{
23
    /**
24
     * @var \ZBateson\MailMimeParser\Message\Part\MimePart parent part
25
     */
26
    protected $parent;
27
28
    /**
29
     * @var StreamInterface a Psr7 stream containing this part's headers,
30
     *      content and children
31
     */
32
    protected $stream;
33
34
    /**
35
     * @var StreamInterface a Psr7 stream containing this part's content
36
     */
37
    protected $contentStream;
38
    
39
    /**
40
     * @var PartStreamFilterManager manages attached filters to $contentHandle
41
     */
42
    protected $partStreamFilterManager;
43
    
44
    /**
45
     * @var string can be used to set an override for content's charset in cases
46
     *      where a user wants to set a default other than ISO-8859-1.
47
     */
48
    protected $charsetOverride;
49
50
    /**
51
     * Sets up class dependencies.
52
     *
53
     * @param PartStreamFilterManager $partStreamFilterManager
54
     * @param StreamInterface $stream
55
     * @param StreamInterface $contentStream
56
     */
57 5
    public function __construct(
58
        PartStreamFilterManager $partStreamFilterManager,
59
        StreamInterface $stream,
60
        StreamInterface $contentStream = null
61
    ) {
62 5
        $this->stream = $stream;
63 5
        $this->contentStream = $contentStream;
64 5
        if ($contentStream !== null) {
65 3
            $partStreamFilterManager->setStream(
66 3
                $contentStream
67
            );
68
        }
69 5
        $this->partStreamFilterManager = $partStreamFilterManager;
70 5
    }
71
72
    /**
73
     * Returns true if there's a content stream associated with the part.
74
     *
75
     * @return boolean
76
     */
77 5
    public function hasContent()
78
    {
79 5
        return ($this->contentStream !== null);
80
    }
81
82
    /**
83
     * Returns true if this part's mime type is text/plain, text/html or has a
84
     * text/* and has a defined 'charset' attribute.
85
     * 
86
     * @return bool
87
     */
88
    public abstract function isTextPart();
89
    
90
    /**
91
     * Returns the mime type of the content.
92
     * 
93
     * @return string
94
     */
95
    public abstract function getContentType();
96
    
97
    /**
98
     * Returns the charset of the content, or null if not applicable/defined.
99
     * 
100
     * @return string
101
     */
102
    public abstract function getCharset();
103
    
104
    /**
105
     * Returns the content's disposition.
106
     * 
107
     * @return string
108
     */
109
    public abstract function getContentDisposition();
110
    
111
    /**
112
     * Returns the content-transfer-encoding used for this part.
113
     * 
114
     * @return string
115
     */
116
    public abstract function getContentTransferEncoding();
117
    
118
    /**
119
     * Returns a filename for the part if one is defined, or null otherwise.
120
     * 
121
     * @return string
122
     */
123
    public function getFilename()
124
    {
125
        return null;
126
    }
127
    
128
    /**
129
     * Returns true if the current part is a mime part.
130
     * 
131
     * @return bool
132
     */
133
    public abstract function isMime();
134
    
135
    /**
136
     * Returns a resource stream handle allowing a user to read the original
137
     * stream (including headers and child parts) that was used to create the
138
     * current part.
139
     * 
140
     * Note that 'rewind()' is called on the resource prior to returning it,
141
     * which may affect other read operations if multiple calls to 'getHandle'
142
     * are used.
143
     * 
144
     * The resource stream is handled by MessagePart and is closed by the
145
     * destructor.
146
     * 
147
     * @return resource the resource handle or null if not set
148
     */
149 2
    public function getHandle()
150
    {
151 2
        if ($this->stream !== null) {
152 2
            $this->stream->rewind();
153 2
            return StreamWrapper::getResource($this->stream);
154
        }
155
        return null;
156
    }
157
158
    /**
159
     * Overrides the default character set used for reading content from content
160
     * streams in cases where a user knows the source charset is not what is
161
     * specified.
162
     * 
163
     * If set, the returned value from MessagePart::getCharset is ignored.
164
     * 
165
     * Note that setting an override on a Message and calling getTextStream,
166
     * getTextContent, getHtmlStream or getHtmlContent will not be applied to
167
     * those sub-parts, unless the text/html part is the Message itself.
168
     * Instead, Message:getTextPart() should be called, and setCharsetOverride
169
     * called on the returned MessagePart.
170
     * 
171
     * @param string $charsetOverride
172
     * @param boolean $onlyIfNoCharset if true, $charsetOverride is used only if
173
     *        getCharset returns null.
174
     */
175 1
    public function setCharsetOverride($charsetOverride, $onlyIfNoCharset = false)
176
    {
177 1
        if (!$onlyIfNoCharset || $this->getCharset() === null) {
178
            $this->charsetOverride = $charsetOverride;
179
        }
180 1
    }
181
182
    /**
183
     * Returns a new resource stream handle for the part's content or null if
184
     * the part doesn't have a content section.
185
     *
186
     * The returned resource handle is a resource stream with decoding filters
187
     * appended to it.  The attached filters are determined by looking at the
188
     * part's Content-Transfer-Encoding and Content-Type headers unless a
189
     * charset override is set.  The following transfer encodings are supported:
190
     *
191
     * - quoted-printable
192
     * - base64
193
     * - x-uuencode
194
     *
195
     * In addition, the charset of the underlying stream is converted to the
196
     * passed $charset if the content is known to be text.
197
     *
198
     * @param string $charset
199
     * @return resource
200
     */
201 4
    public function getContentResourceHandle($charset = MailMimeParser::DEFAULT_CHARSET)
202
    {
203 4
        $stream = $this->getContentStream($charset);
204 4
        if ($stream !== null) {
205 2
            return StreamWrapper::getResource($stream);
206
        }
207 2
        return null;
208
    }
209
210
    /**
211
     * Returns the StreamInterface for the part's content or null if the part
212
     * doesn't have a content section.
213
     *
214
     * Because the returned stream may be a shared object if called multiple
215
     * times, the function isn't exposed publicly.  If called multiple times
216
     * with the same $charset, and the value of the part's
217
     * Content-Transfer-Encoding header not having changed, the returned stream
218
     * is the same instance and may need to be rewound.
219
     *
220
     * Note that PartStreamFilterManager rewinds the stream before returning it.
221
     *
222
     * @param string $charset
223
     * @return StreamInterface
224
     */
225 5
    protected function getContentStream($charset = MailMimeParser::DEFAULT_CHARSET)
226
    {
227 5
        if ($this->hasContent()) {
228 3
            $tr = $this->getContentTransferEncoding();
229 3
            $ch = ($this->charsetOverride !== null) ? $this->charsetOverride : $this->getCharset();
230 3
            return $this->partStreamFilterManager->getContentStream(
231 3
                $tr,
232 3
                $ch,
233 3
                $charset
234
            );
235
        }
236 2
        return null;
237
    }
238
239
    /**
240
     * Shortcut to reading stream content and assigning it to a string.  Returns
241
     * null if the part doesn't have a content stream.
242
     * 
243
     * The returned string is encoded to the passed $charset character encoding,
244
     * defaulting to UTF-8.
245
     *
246
     * @return string
247
     */
248 2
    public function getContent($charset = MailMimeParser::DEFAULT_CHARSET)
249
    {
250 2
        $stream = $this->getContentStream($charset);
251 2
        if ($stream !== null) {
252 1
            return $stream->getContents();
253
        }
254 1
        return null;
255
    }
256
257
    /**
258
     * Returns this part's parent.
259
     *
260
     * @return \ZBateson\MailMimeParser\Message\Part\MimePart
261
     */
262 1
    public function getParent()
263
    {
264 1
        return $this->parent;
265
    }
266
}
267