Test Failed
Push — 2.0 ( 4d4d2f...3431b8 )
by Zaahid
04:28
created

PartBuilder::getChild()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
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\Parser;
8
9
use GuzzleHttp\Psr7\StreamWrapper;
10
use Psr\Http\Message\StreamInterface;
11
12
/**
13
 * Holds information about a part while it's being parsed, proxies calls between
14
 * parsed part containers (ParsedPartChildrenContainer,
15
 * ParsedPartStreamContainer) and the parser as more parts need to be parsed.
16
 *
17
 * The class holds:
18
 *  - a HeaderContainer to hold headers
19
 *  - stream positions (part start/end positions, content start/end)
20
 *  - parser markers, e.g. 'mimeBoundary, 'endBoundaryFound',
21
 *    'parentBoundaryFound', 'canHaveHeaders', 'isNonMimePart'
22
 *  - properties for UUEncoded parts (filename, mode)
23
 *  - the message's psr7 stream and a resource handle created from it (held
24
 *    only for a top-level PartBuilder representing the message, child
25
 *    PartBuilders do not duplicate/hold a separate stream).
26
 *  - ParsedPartChildrenContainer, ParsedPartStreamContainer to update children
27
 *    and streams dynamically as a part is parsed.
28
 * @author Zaahid Bateson
29
 */
30
class PartBuilder
31
{
32
    /**
33
     * @var int The offset read start position for this part (beginning of
34
     * headers) in the message's stream.
35
     */
36
    protected $streamPartStartPos = null;
37
    
38
    /**
39
     * @var int The offset read end position for this part.  If the part is a
40
     * multipart mime part, the end position is after all of this parts
41
     * children.
42
     */
43
    protected $streamPartEndPos = null;
44
    
45
    /**
46
     * @var int The offset read start position in the message's stream for the
47
     * beginning of this part's content (body).
48
     */
49
    protected $streamContentStartPos = null;
50
    
51
    /**
52
     * @var int The offset read end position in the message's stream for the
53
     * end of this part's content (body).
54
     */
55
    protected $streamContentEndPos = null;
56
57
    /**
58
     * @var StreamInterface the raw message input stream for a message, or null
59
     *      for a child part.
60
     */
61
    protected $messageStream = null;
62
63
    /**
64
     * @var resource the raw message input stream handle constructed from
65
     *      $messageStream or null for a child part
66
     */
67
    protected $messageHandle = null;
68
69
    private $parent = null;
70
71
    public function __construct(StreamInterface $messageStream = null, PartBuilder $parent = null)
72
    {
73
        $this->messageStream = $messageStream;
74
        $this->parent = $parent;
75
        if ($messageStream !== null) {
76
            $this->messageHandle = StreamWrapper::getResource($messageStream);
77
        }
78
        $this->setStreamPartStartPos($this->getMessageResourceHandlePos());
79
    }
80
81
    public function __destruct()
82
    {
83
        if ($this->messageHandle) {
84
            fclose($this->messageHandle);
85
        }
86
    }
87
88
    public function getStream()
89
    {
90
        return ($this->parent !== null) ?
91
            $this->parent->getStream() :
92
            $this->messageStream;
93
    }
94
95
    public function getMessageResourceHandle()
96
    {
97
        return ($this->parent !== null) ?
98
            $this->parent->getMessageResourceHandle() :
99
            $this->messageHandle;
100
    }
101
102
    public function getMessageResourceHandlePos()
103
    {
104
        return ftell($this->getMessageResourceHandle());
105
    }
106
107
    /**
108
     * Returns the offset for this part's stream within its parent stream.
109
     *
110
     * @return int
111
     */
112
    public function getStreamPartStartOffset()
113
    {
114
        return $this->streamPartStartPos;
115
    }
116
117
    /**
118
     * Returns the length of this part's stream.
119
     *
120
     * @return int
121
     */
122
    public function getStreamPartLength()
123
    {
124
        return $this->streamPartEndPos - $this->streamPartStartPos;
125
    }
126
127
    /**
128
     * Returns the offset for this part's content within its part stream.
129
     *
130
     * @return int
131
     */
132
    public function getStreamContentStartOffset()
133
    {
134
        return $this->streamContentStartPos;
135
    }
136
137
    /**
138
     * Returns the length of this part's content stream.
139
     *
140
     * @return int
141
     */
142
    public function getStreamContentLength()
143
    {
144
        return $this->streamContentEndPos - $this->streamContentStartPos;
145
    }
146
147
    /**
148
     * Sets the start position of the part in the input stream.
149
     * 
150
     * @param int $streamPartStartPos
151
     */
152
    public function setStreamPartStartPos($streamPartStartPos)
153
    {
154
        $this->streamPartStartPos = $streamPartStartPos;
155
    }
156
157
    /**
158
     * Sets the end position of the part in the input stream, and also calls
159
     * parent->setParentStreamPartEndPos to expand to parent parts.
160
     * 
161
     * @param int $streamPartEndPos
162
     */
163
    public function setStreamPartEndPos($streamPartEndPos)
164
    {
165
        $this->streamPartEndPos = $streamPartEndPos;
166
        if ($this->parent !== null) {
167
            $this->parent->setStreamPartEndPos($streamPartEndPos);
168
        }
169
    }
170
171
    /**
172
     * Sets the start position of the content in the input stream.
173
     * 
174
     * @param int $streamContentStartPos
175
     */
176
    public function setStreamContentStartPos($streamContentStartPos)
177
    {
178
        $this->streamContentStartPos = $streamContentStartPos;
179
    }
180
181
    /**
182
     * Sets the end position of the content and part in the input stream.
183
     * 
184
     * @param int $streamContentEndPos
185
     */
186
    public function setStreamPartAndContentEndPos($streamContentEndPos)
187
    {
188
        $this->streamContentEndPos = $streamContentEndPos;
189
        $this->setStreamPartEndPos($streamContentEndPos);
190
    }
191
192
    public function isContentParsed()
193
    {
194
        return ($this->streamContentEndPos !== null);
195
    }
196
}
197