Test Failed
Push — master ( e258e4...a626ba )
by Zaahid
15:25
created

getTransferEncodingDecoratedStream()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 22
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
eloc 17
c 0
b 0
f 0
dl 0
loc 22
rs 9.3888
ccs 0
cts 0
cp 0
cc 5
nc 5
nop 3
crap 30
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 100
     */
34
    protected bool $throwExceptionReadingPartContentFromUnsupportedCharsets;
35 100
36 100
    public function __construct(bool $throwExceptionReadingPartContentFromUnsupportedCharsets)
37 100
    {
38 100
        $this->throwExceptionReadingPartContentFromUnsupportedCharsets = $throwExceptionReadingPartContentFromUnsupportedCharsets;
39 100
    }
40
41
    /**
42
     * Returns a SeekingLimitStream using $part->getStreamPartLength() and
43
     * $part->getStreamPartStartPos()
44
     */
45
    public function getLimitedPartStream(PartBuilder $part) : StreamInterface
46 104
    {
47
        return $this->newLimitStream(
48 104
            $part->getStream(),
49 104
            $part->getStreamPartLength(),
50 103
            $part->getStreamPartStartPos()
51 103
        );
52 103
    }
53 103
54 103
    /**
55
     * Returns a SeekingLimitStream using $part->getStreamContentLength() and
56 36
     * $part->getStreamContentStartPos()
57
     */
58
    public function getLimitedContentStream(PartBuilder $part) : ?StreamInterface
59
    {
60
        $length = $part->getStreamContentLength();
61
        if ($length !== 0) {
62 104
            return $this->newLimitStream(
63
                $part->getStream(),
64 104
                $part->getStreamContentLength(),
65 104
                $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 104
            );
67 104
        }
68 104
        return null;
69
    }
70
71
    /**
72
     * Creates and returns a SeekingLimitedStream.
73
     */
74
    private function newLimitStream(StreamInterface $stream, int $length, int $start) : StreamInterface
75 104
    {
76
        return new SeekingLimitStream(
77 104
            $this->newNonClosingStream($stream),
78
            $length,
79
            $start
80
        );
81
    }
82
83 40
    /**
84
     * Creates and returns a SeekingLimitedStream without limits, so it's a
85 40
     * stream that preserves its current position on the underlying stream it
86
     * reads from.
87
     */
88
    public function newSeekingStream(StreamInterface $stream) : StreamInterface
89
    {
90
        return new SeekingLimitStream($this->newNonClosingStream($stream));
91
    }
92 48
93
    /**
94 48
     * Creates a non-closing stream that doesn't close it's internal stream when
95 48
     * closing/detaching.
96 48
     */
97
    public function newNonClosingStream(StreamInterface $stream) : StreamInterface
98
    {
99
        return new NonClosingStream($stream);
100
    }
101
102 59
    /**
103
     * Creates a ChunkSplitStream.
104 59
     */
105
    public function newChunkSplitStream(StreamInterface $stream) : StreamInterface
106
    {
107
        return new ChunkSplitStream($stream);
108
    }
109
110 9
    /**
111
     * Creates and returns a Base64Stream with an internal
112 9
     * PregReplaceFilterStream that filters out non-base64 characters.
113
     */
114
    public function newBase64Stream(StreamInterface $stream) : StreamInterface
115
    {
116
        return new Base64Stream(
117
            new PregReplaceFilterStream($stream, '/[^a-zA-Z0-9\/\+=]/', '')
118 88
        );
119
    }
120 88
121
    /**
122
     * Creates and returns a QuotedPrintableStream.
123
     */
124
    public function newQuotedPrintableStream(StreamInterface $stream) : StreamInterface
125
    {
126 106
        return new QuotedPrintableStream($stream);
127
    }
128 106
129
    /**
130
     * Creates and returns a UUStream
131
     */
132
    public function newUUStream(StreamInterface $stream) : StreamInterface
133
    {
134 94
        return new UUStream($stream);
135
    }
136 94
137
    public function getTransferEncodingDecoratedStream(StreamInterface $stream, ?string $transferEncoding, ?string $filename = null) : StreamInterface
138
    {
139
        $decorated = null;
140
        switch ($transferEncoding) {
141
            case 'quoted-printable':
142
                $decorated = $this->newQuotedPrintableStream($stream);
143
                break;
144
            case 'base64':
145
                $decorated = $this->newBase64Stream(
146
                    $this->newChunkSplitStream($stream)
147
                );
148
                break;
149
            case 'x-uuencode':
150
                $decorated = $this->newUUStream($stream);
151
                if ($filename !== null) {
152
                    $decorated->setFilename($filename);
153
                }
154
                break;
155
            default:
156
                return $stream;
157
        }
158
        return $decorated;
159
    }
160
161
    /**
162
     * Creates and returns a CharsetStream
163
     */
164
    public function newCharsetStream(StreamInterface $stream, string $streamCharset, string $stringCharset) : StreamInterface
165
    {
166
        return new CharsetStream($stream, $streamCharset, $stringCharset);
167
    }
168
169
    /**
170
     * Creates and returns a MessagePartStream
171
     */
172
    public function newMessagePartStream(IMessagePart $part) : MessagePartStreamDecorator
173
    {
174
        return new MessagePartStream($this, $part, $this->throwExceptionReadingPartContentFromUnsupportedCharsets);
175
    }
176
177
    /**
178
     * Creates and returns a DecoratedCachingStream
179
     */
180
    public function newDecoratedCachingStream(StreamInterface $stream, callable $decorator) : StreamInterface
181
    {
182
        // seems to perform best locally, would be good to test this out more
183
        return new DecoratedCachingStream($stream, $decorator, 204800);
184
    }
185
186
    /**
187
     * Creates and returns a HeaderStream
188
     */
189
    public function newHeaderStream(IMessagePart $part) : StreamInterface
190
    {
191
        return new HeaderStream($part);
192
    }
193
194
    public function newDecoratedMessagePartStream(IMessagePart $part, StreamInterface $stream) : MessagePartStreamDecorator
195
    {
196
        return new MessagePartStreamDecorator($part, $stream);
197
    }
198
}
199