StreamFactory::newDecoratedMessagePartStream()   A
last analyzed

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 2
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\Stream;
9
10
use Psr\Http\Message\StreamInterface;
11
use ZBateson\MailMimeParser\Message\IMessagePart;
12
use ZBateson\MailMimeParser\Parser\PartBuilder;
13
use ZBateson\StreamDecorators\Base64Stream;
14
use ZBateson\StreamDecorators\CharsetStream;
15
use ZBateson\StreamDecorators\ChunkSplitStream;
16
use ZBateson\StreamDecorators\DecoratedCachingStream;
17
use ZBateson\StreamDecorators\NonClosingStream;
18
use ZBateson\StreamDecorators\PregReplaceFilterStream;
19
use ZBateson\StreamDecorators\QuotedPrintableStream;
20
use ZBateson\StreamDecorators\SeekingLimitStream;
21
use ZBateson\StreamDecorators\UUStream;
22
23
/**
24
 * Factory class for Psr7 stream decorators used in MailMimeParser.
25
 *
26
 * @author Zaahid Bateson
27
 */
28
class StreamFactory
29
{
30
    /**
31
     * @var bool if true, saving a content stream with an unsupported charset
32
     *      will be written in the default charset.
33
     */
34
    protected bool $throwExceptionReadingPartContentFromUnsupportedCharsets;
35
36 3
    public function __construct(bool $throwExceptionReadingPartContentFromUnsupportedCharsets)
37
    {
38 3
        $this->throwExceptionReadingPartContentFromUnsupportedCharsets = $throwExceptionReadingPartContentFromUnsupportedCharsets;
39
    }
40
41
    /**
42
     * Returns a SeekingLimitStream using $part->getStreamPartLength() and
43
     * $part->getStreamPartStartPos()
44
     */
45 101
    public function getLimitedPartStream(PartBuilder $part) : StreamInterface
46
    {
47 101
        return $this->newLimitStream(
48 101
            $part->getStream(),
49 101
            $part->getStreamPartLength(),
50 101
            $part->getStreamPartStartPos()
51 101
        );
52
    }
53
54
    /**
55
     * Returns a SeekingLimitStream using $part->getStreamContentLength() and
56
     * $part->getStreamContentStartPos()
57
     */
58 106
    public function getLimitedContentStream(PartBuilder $part) : ?StreamInterface
59
    {
60 106
        $length = $part->getStreamContentLength();
61 106
        if ($length !== 0) {
62 105
            return $this->newLimitStream(
63 105
                $part->getStream(),
64 105
                $part->getStreamContentLength(),
65 105
                $part->getStreamContentStartPos()
0 ignored issues
show
Bug introduced by
It seems like $part->getStreamContentStartPos() can also be of type null; however, parameter $start of ZBateson\MailMimeParser\...ctory::newLimitStream() does only seem to accept integer, 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

65
                /** @scrutinizer ignore-type */ $part->getStreamContentStartPos()
Loading history...
66 105
            );
67
        }
68 36
        return null;
69
    }
70
71
    /**
72
     * Creates and returns a SeekingLimitedStream.
73
     */
74 106
    private function newLimitStream(StreamInterface $stream, int $length, int $start) : StreamInterface
75
    {
76 106
        return new SeekingLimitStream(
77 106
            $this->newNonClosingStream($stream),
78 106
            $length,
79 106
            $start
80 106
        );
81
    }
82
83
    /**
84
     * Creates and returns a SeekingLimitedStream without limits, so it's a
85
     * stream that preserves its current position on the underlying stream it
86
     * reads from.
87
     */
88 94
    public function newSeekingStream(StreamInterface $stream) : StreamInterface
89
    {
90 94
        return new SeekingLimitStream($this->newNonClosingStream($stream));
91
    }
92
93
    /**
94
     * Creates a non-closing stream that doesn't close it's internal stream when
95
     * closing/detaching.
96
     */
97 106
    public function newNonClosingStream(StreamInterface $stream) : StreamInterface
98
    {
99 106
        return new NonClosingStream($stream);
100
    }
101
102
    /**
103
     * Creates a ChunkSplitStream.
104
     */
105 48
    public function newChunkSplitStream(StreamInterface $stream) : StreamInterface
106
    {
107 48
        return new ChunkSplitStream($stream);
108
    }
109
110
    /**
111
     * Creates and returns a Base64Stream with an internal
112
     * PregReplaceFilterStream that filters out non-base64 characters.
113
     */
114 48
    public function newBase64Stream(StreamInterface $stream) : StreamInterface
115
    {
116 48
        return new Base64Stream(
117 48
            new PregReplaceFilterStream($stream, '/[^a-zA-Z0-9\/\+=]/', '')
118 48
        );
119
    }
120
121
    /**
122
     * Creates and returns a QuotedPrintableStream.
123
     */
124 61
    public function newQuotedPrintableStream(StreamInterface $stream) : StreamInterface
125
    {
126 61
        return new QuotedPrintableStream($stream);
127
    }
128
129
    /**
130
     * Creates and returns a UUStream
131
     */
132 9
    public function newUUStream(StreamInterface $stream) : StreamInterface
133
    {
134 9
        return new UUStream($stream);
135
    }
136
137 105
    public function getTransferEncodingDecoratedStream(StreamInterface $stream, ?string $transferEncoding, ?string $filename = null) : StreamInterface
138
    {
139 105
        $decorated = null;
140
        switch ($transferEncoding) {
141 105
            case 'quoted-printable':
142 60
                $decorated = $this->newQuotedPrintableStream($stream);
143 60
                break;
144 89
            case 'base64':
145 47
                $decorated = $this->newBase64Stream(
146 47
                    $this->newChunkSplitStream($stream)
147 47
                );
148 47
                break;
149 77
            case 'x-uuencode':
150 8
                $decorated = $this->newUUStream($stream);
151 8
                if ($filename !== null) {
152 8
                    $decorated->setFilename($filename);
153
                }
154 8
                break;
155
            default:
156 77
                return $stream;
157
        }
158 83
        return $decorated;
159
    }
160
161
    /**
162
     * Creates and returns a CharsetStream
163
     */
164 90
    public function newCharsetStream(StreamInterface $stream, string $streamCharset, string $stringCharset) : StreamInterface
165
    {
166 90
        return new CharsetStream($stream, $streamCharset, $stringCharset);
167
    }
168
169
    /**
170
     * Creates and returns a MessagePartStream
171
     */
172 108
    public function newMessagePartStream(IMessagePart $part) : MessagePartStreamDecorator
173
    {
174 108
        return new MessagePartStream($this, $part, $this->throwExceptionReadingPartContentFromUnsupportedCharsets);
175
    }
176
177
    /**
178
     * Creates and returns a DecoratedCachingStream
179
     */
180 94
    public function newDecoratedCachingStream(StreamInterface $stream, callable $decorator) : StreamInterface
181
    {
182
        // seems to perform best locally, would be good to test this out more
183 94
        return new DecoratedCachingStream($stream, $decorator, 204800);
184
    }
185
186
    /**
187
     * Creates and returns a HeaderStream
188
     */
189 95
    public function newHeaderStream(IMessagePart $part) : StreamInterface
190
    {
191 95
        return new HeaderStream($part);
192
    }
193
194 105
    public function newDecoratedMessagePartStream(IMessagePart $part, StreamInterface $stream) : MessagePartStreamDecorator
195
    {
196 105
        return new MessagePartStreamDecorator($part, $stream);
197
    }
198
}
199