Passed
Push — master ( d59e0c...655c99 )
by Zaahid
08:54
created

setStreamPartAndContentEndPos()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 7
c 0
b 0
f 0
dl 0
loc 10
ccs 7
cts 7
cp 1
rs 10
cc 2
nc 2
nop 1
crap 2
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\Parser\Proxy;
9
10
use ZBateson\MailMimeParser\Header\HeaderConsts;
11
use ZBateson\MailMimeParser\Message\IMessagePart;
12
13
/**
14
 * A bi-directional parser-to-part proxy for MimeParser and IMimeParts.
15
 *
16
 * @author Zaahid Bateson
17
 */
18
class ParserMimePartProxy extends ParserPartProxy
19
{
20
    /**
21
     * @var bool set to true once the end boundary of the currently-parsed
22
     *      part is found.
23
     */
24
    protected $endBoundaryFound = false;
25
26
    /**
27
     * @var bool set to true once a boundary belonging to this parent's part
28
     *      is found.
29
     */
30
    protected $parentBoundaryFound = false;
31
32
    /**
33
     * @var bool|null|string FALSE if not queried for in the content-type
34
     *      header of this part, NULL if the current part does not have a
35
     *      boundary, and otherwise contains the value of the boundary parameter
36
     *      of the content-type header if the part contains one.
37
     */
38
    protected $mimeBoundary = false;
39
40
    /**
41
     * @var bool true once all children of this part have been parsed.
42
     */
43
    protected $allChildrenParsed = false;
44
45
    /**
46
     * @var ParserPartProxy[] Parsed children used as a 'first-in-first-out'
47
     *      stack as children are parsed.
48
     */
49
    protected $children = [];
50
51
    /**
52
     * @var ParserPartProxy Reference to the last child added to this part.
53
     */
54
    protected $lastAddedChild = null;
55
56
    /**
57
     * Ensures that the last child added to this part is fully parsed (content
58
     * and children).
59
     */
60 107
    protected function ensureLastChildParsed() : self
61
    {
62 107
        if ($this->lastAddedChild !== null) {
63 77
            $this->lastAddedChild->parseAll();
64
        }
65 107
        return $this;
66
    }
67
68
    /**
69
     * Parses the next child of this part and adds it to the 'stack' of
70
     * children.
71
     */
72 107
    protected function parseNextChild() : self
73
    {
74 107
        if ($this->allChildrenParsed) {
75 20
            return $this;
76
        }
77 107
        $this->parseContent();
78 107
        $this->ensureLastChildParsed();
79 107
        $next = $this->parser->parseNextChild($this);
80 107
        if ($next !== null) {
81 77
            $this->children[] = $next;
82 77
            $this->lastAddedChild = $next;
83
        } else {
84 107
            $this->allChildrenParsed = true;
85
        }
86 107
        return $this;
87
    }
88
89
    /**
90
     * Returns the next child part if one exists, popping it from the internal
91
     * 'stack' of children, attempting to parse a new one if the stack is empty,
92
     * and returning null if there are no more children.
93
     *
94
     * @return IMessagePart|null the child part.
95
     */
96 105
    public function popNextChild()
97
    {
98 105
        if (empty($this->children)) {
99 105
            $this->parseNextChild();
100
        }
101 105
        $proxy = \array_shift($this->children);
102 105
        return ($proxy !== null) ? $proxy->getPart() : null;
103
    }
104
105
    /**
106
     * Parses all content and children for this part.
107
     * @return static
108
     */
109 105
    public function parseAll()
110
    {
111 105
        $this->parseContent();
112 105
        while (!$this->allChildrenParsed) {
113 27
            $this->parseNextChild();
114
        }
115 105
        return $this;
116
    }
117
118
    /**
119
     * Returns a ParameterHeader representing the parsed Content-Type header for
120
     * this part.
121
     *
122
     * @return ?\ZBateson\MailMimeParser\Header\IHeader
123
     */
124 79
    public function getContentType()
125
    {
126 79
        return $this->getHeaderContainer()->get(HeaderConsts::CONTENT_TYPE);
127
    }
128
129
    /**
130
     * Returns the parsed boundary parameter of the Content-Type header if set
131
     * for a multipart message part.
132
     *
133
     * @return string
134
     */
135 78
    public function getMimeBoundary()
136
    {
137 78
        if ($this->mimeBoundary === false) {
138 78
            $this->mimeBoundary = null;
139 78
            $contentType = $this->getContentType();
140 78
            if ($contentType !== null) {
141 76
                $this->mimeBoundary = $contentType->getValueFor('boundary');
0 ignored issues
show
Bug introduced by
The method getValueFor() does not exist on ZBateson\MailMimeParser\Header\IHeader. Did you maybe mean getValue()? ( Ignorable by Annotation )

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

141
                /** @scrutinizer ignore-call */ 
142
                $this->mimeBoundary = $contentType->getValueFor('boundary');

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
142
            }
143
        }
144 78
        return $this->mimeBoundary;
145
    }
146
147
    /**
148
     * Returns true if the passed $line of read input matches this part's mime
149
     * boundary, or any of its parent's mime boundaries for a multipart message.
150
     *
151
     * If the passed $line is the ending boundary for the current part,
152
     * $this->isEndBoundaryFound will return true after.
153
     *
154
     * @return bool
155
     */
156 76
    public function setEndBoundaryFound(string $line)
157
    {
158 76
        $boundary = $this->getMimeBoundary();
159 76
        if ($this->getParent() !== null && $this->getParent()->setEndBoundaryFound($line)) {
0 ignored issues
show
Bug introduced by
The method setEndBoundaryFound() does not exist on ZBateson\MailMimeParser\...r\Proxy\ParserPartProxy. It seems like you code against a sub-type of ZBateson\MailMimeParser\...r\Proxy\ParserPartProxy such as ZBateson\MailMimeParser\...oxy\ParserMimePartProxy. ( Ignorable by Annotation )

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

159
        if ($this->getParent() !== null && $this->getParent()->/** @scrutinizer ignore-call */ setEndBoundaryFound($line)) {
Loading history...
160 74
            $this->parentBoundaryFound = true;
161 74
            return true;
162 76
        } elseif ($boundary !== null) {
0 ignored issues
show
introduced by
The condition $boundary !== null is always true.
Loading history...
163 74
            if ($line === "--$boundary--") {
164 74
                $this->endBoundaryFound = true;
165 74
                return true;
166 74
            } elseif ($line === "--$boundary") {
167 74
                return true;
168
            }
169
        }
170 38
        return false;
171
    }
172
173
    /**
174
     * Returns true if the parser passed an input line to setEndBoundary that
175
     * matches a parent's mime boundary, and the following input belongs to a
176
     * new part under its parent.
177
     *
178
     */
179 103
    public function isParentBoundaryFound() : bool
180
    {
181 103
        return ($this->parentBoundaryFound);
182
    }
183
184
    /**
185
     * Returns true if an end boundary was found for this part.
186
     *
187
     */
188 76
    public function isEndBoundaryFound() : bool
189
    {
190 76
        return ($this->endBoundaryFound);
191
    }
192
193
    /**
194
     * Called once EOF is reached while reading content.  The method sets the
195
     * flag used by isParentBoundaryFound() to true on this part and all parent
196
     * parts.
197
     *
198
     * @return static
199
     */
200 97
    public function setEof() : self
201
    {
202 97
        $this->parentBoundaryFound = true;
203 97
        if ($this->getParent() !== null) {
204 66
            $this->getParent()->setEof();
0 ignored issues
show
Bug introduced by
The method setEof() does not exist on ZBateson\MailMimeParser\...r\Proxy\ParserPartProxy. It seems like you code against a sub-type of ZBateson\MailMimeParser\...r\Proxy\ParserPartProxy such as ZBateson\MailMimeParser\...oxy\ParserMimePartProxy. ( Ignorable by Annotation )

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

204
            $this->getParent()->/** @scrutinizer ignore-call */ setEof();
Loading history...
205
        }
206 97
        return $this;
207
    }
208
209
    /**
210
     * Overridden to set a 0-length content length, and a stream end pos of -2
211
     * if the passed end pos is before the start pos (can happen if a mime
212
     * end boundary doesn't have an empty line before the next parent start
213
     * boundary).
214
     *
215
     * @return static
216
     */
217 104
    public function setStreamPartAndContentEndPos(int $streamContentEndPos)
218
    {
219 104
        $start = $this->getStreamContentStartPos();
220 104
        if ($streamContentEndPos - $start < 0) {
221 28
            parent::setStreamPartAndContentEndPos($start);
222 28
            $this->setStreamPartEndPos($streamContentEndPos);
223
        } else {
224 104
            parent::setStreamPartAndContentEndPos($streamContentEndPos);
225
        }
226 104
        return $this;
227
    }
228
229
    /**
230
     * Sets the length of the last line ending read by MimeParser (e.g. 2 for
231
     * '\r\n', or 1 for '\n').
232
     *
233
     * The line ending may not belong specifically to this part, so
234
     * ParserMimePartProxy simply calls setLastLineEndingLength on its parent,
235
     * which must eventually reach a ParserMessageProxy which actually stores
236
     * the length.
237
     *
238
     * @return static
239
     */
240 74
    public function setLastLineEndingLength(int $length)
241
    {
242 74
        $this->getParent()->setLastLineEndingLength($length);
0 ignored issues
show
Bug introduced by
The method setLastLineEndingLength() does not exist on ZBateson\MailMimeParser\...r\Proxy\ParserPartProxy. It seems like you code against a sub-type of ZBateson\MailMimeParser\...r\Proxy\ParserPartProxy such as ZBateson\MailMimeParser\...oxy\ParserMimePartProxy. ( Ignorable by Annotation )

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

242
        $this->getParent()->/** @scrutinizer ignore-call */ setLastLineEndingLength($length);
Loading history...
243 74
        return $this;
244
    }
245
246
    /**
247
     * Returns the length of the last line ending read by MimeParser (e.g. 2 for
248
     * '\r\n', or 1 for '\n').
249
     *
250
     * The line ending may not belong specifically to this part, so
251
     * ParserMimePartProxy simply calls getLastLineEndingLength on its parent,
252
     * which must eventually reach a ParserMessageProxy which actually keeps
253
     * the length and returns it.
254
     *
255
     * @return int the length of the last line ending read
256
     */
257 74
    public function getLastLineEndingLength() : int
258
    {
259 74
        return $this->getParent()->getLastLineEndingLength();
0 ignored issues
show
Bug introduced by
The method getLastLineEndingLength() does not exist on ZBateson\MailMimeParser\...r\Proxy\ParserPartProxy. It seems like you code against a sub-type of ZBateson\MailMimeParser\...r\Proxy\ParserPartProxy such as ZBateson\MailMimeParser\...oxy\ParserMimePartProxy. ( Ignorable by Annotation )

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

259
        return $this->getParent()->/** @scrutinizer ignore-call */ getLastLineEndingLength();
Loading history...
260
    }
261
}
262