HeaderStream   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 70
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 11
eloc 24
c 1
b 0
f 0
dl 0
loc 70
ccs 29
cts 29
cp 1
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A update() 0 4 2
A getPartHeadersIterator() 0 12 4
A __destruct() 0 3 1
A writePartHeadersTo() 0 7 2
A __construct() 0 8 1
A createStream() 0 6 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 ArrayIterator;
11
use GuzzleHttp\Psr7;
12
use Psr\Http\Message\StreamInterface;
13
use SplObserver;
14
use SplSubject;
15
use Traversable;
16
use ZBateson\MailMimeParser\Header\HeaderConsts;
17
use ZBateson\MailMimeParser\Message\IMessagePart;
18
use ZBateson\MailMimeParser\Message\IMimePart;
19
20
/**
21
 * Psr7 stream decorator implementation providing a readable stream for a part's
22
 * headers.
23
 *
24
 * HeaderStream is only used by a MimePart parent.  It can accept any
25
 * MessagePart - for non-MimeParts, only type headers are generated based on
26
 * available information.
27
 *
28
 * @author Zaahid Bateson
29
 */
30
class HeaderStream extends MessagePartStreamDecorator implements SplObserver, StreamInterface
31
{
32
    /**
33
     * @var IMessagePart the part to read from.
34
     */
35
    protected IMessagePart $part;
36
37 96
    public function __construct(IMessagePart $part)
38
    {
39 96
        parent::__construct($part);
40 96
        $part->attach($this);
41
42
        // unsetting the property forces the first access to go through
43
        // __get().
44 96
        unset($this->stream);
45
    }
46
47 7
    public function __destruct()
48
    {
49 7
        $this->part->detach($this);
50
    }
51
52 3
    public function update(SplSubject $subject) : void
53
    {
54 3
        if ($this->stream !== null) {
55 3
            $this->stream = $this->createStream();
56
        }
57
    }
58
59
    /**
60
     * Returns a header array for the current part.
61
     *
62
     * If the part is not a MimePart, Content-Type, Content-Disposition and
63
     * Content-Transfer-Encoding headers are generated manually.
64
     */
65 96
    private function getPartHeadersIterator() : Traversable
66
    {
67 96
        if ($this->part instanceof IMimePart) {
68 95
            return $this->part->getRawHeaderIterator();
0 ignored issues
show
Bug introduced by
The method getRawHeaderIterator() does not exist on ZBateson\MailMimeParser\Message\IMessagePart. It seems like you code against a sub-type of ZBateson\MailMimeParser\Message\IMessagePart such as ZBateson\MailMimeParser\Message\MimePart or ZBateson\MailMimeParser\Message\IMimePart or ZBateson\MailMimeParser\Message\MimePart. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

68
            return $this->part->/** @scrutinizer ignore-call */ getRawHeaderIterator();
Loading history...
69 4
        } elseif ($this->part->getParent() !== null && $this->part->getParent()->isMime()) {
70 3
            return new ArrayIterator([
71 3
                [HeaderConsts::CONTENT_TYPE, $this->part->getContentType()],
72 3
                [HeaderConsts::CONTENT_DISPOSITION, $this->part->getContentDisposition()],
73 3
                [HeaderConsts::CONTENT_TRANSFER_ENCODING, $this->part->getContentTransferEncoding()]
74 3
            ]);
75
        }
76 2
        return new ArrayIterator();
77
    }
78
79
    /**
80
     * Writes out headers for $this->part and follows them with an empty line.
81
     */
82 96
    public function writePartHeadersTo(StreamInterface $stream) : static
83
    {
84 96
        foreach ($this->getPartHeadersIterator() as $header) {
85 96
            $stream->write("{$header[0]}: {$header[1]}\r\n");
86
        }
87 96
        $stream->write("\r\n");
88 96
        return $this;
89
    }
90
91
    /**
92
     * Creates the underlying stream lazily when required.
93
     */
94 96
    protected function createStream() : StreamInterface
95
    {
96 96
        $stream = Psr7\Utils::streamFor();
97 96
        $this->writePartHeadersTo($stream);
98 96
        $stream->rewind();
99 96
        return $stream;
100
    }
101
}
102