Completed
Push — master ( 7a0fb6...891643 )
by Asmir
24:50 queued 22:48
created

MimeParser::createHeadersSet()   C

Complexity

Conditions 17
Paths 21

Size

Total Lines 49
Code Lines 38

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 219.9815

Importance

Changes 0
Metric Value
dl 0
loc 49
ccs 5
cts 45
cp 0.1111
rs 5.1117
c 0
b 0
f 0
cc 17
eloc 38
nc 21
nop 1
crap 219.9815

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Goetas\Mail\ToSwiftMailParser;
4
5
use Goetas\Mail\ToSwiftMailParser\Mime\ContentDecoder;
6
use Goetas\Mail\ToSwiftMailParser\Mime\HeaderDecoder;
7
8
class MimeParser
9
{
10
    protected $removeHeaders = array("Received", "From", "X-Original-To", "MIME-Version", "Received-SPF", "Delivered-To");
11
    protected $allowedHeaders = array("return-path", "subject");
12
    private $cache;
13
    private $grammar;
14
    private $contentDecoder;
15
    private $headerDecoder;
16
17 5
    public function __construct(array $allowedHeaders = array(), array $removeHeaders = array())
18
    {
19 5
        $this->cache = \Swift_DependencyContainer::getInstance()->lookup('cache');
20 5
        $this->grammar = \Swift_DependencyContainer::getInstance()->lookup('mime.grammar');
21 5
        $this->contentDecoder = new ContentDecoder ();
22 5
        $this->headerDecoder = new HeaderDecoder ();
23
24 5
        $this->allowedHeaders = array_merge($this->allowedHeaders, $allowedHeaders);
25 5
        $this->removeHeaders = array_merge($this->removeHeaders, $removeHeaders);
26 5
    }
27
28 1
    public function parseString($string, $fillHeaders = false, \Swift_Mime_MimeEntity $message = null)
29
    {
30 1
        $fp = fopen("php://memory", "wb");
31 1
        fwrite($fp, $string);
32 1
        rewind($fp);
33 1
        $message = $this->parseStream($fp, $fillHeaders, $message);
0 ignored issues
show
Documentation introduced by
$fp is of type resource, but the function expects a object<Goetas\Mail\ToSwiftMailParser\stream>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
34 1
        fclose($fp);
35 1
        return $message;
36
    }
37
38
    /**
39
     *
40
     * @param stream $stream
41
     * @param boolean $fillHeaders (default to false)
42
     * @param \Swift_Mime_MimeEntity $message (default to null)
43
     * @return Swift_Mime_MimeEntity|\Swift_Message
44
     */
45 5
    public function parseStream($stream, $fillHeaders = false, \Swift_Mime_MimeEntity $message = null)
46
    {
47 5
        $partHeaders = $this->extractHeaders($stream);
48
49 5
        $filteredHeaders = $this->filterHeaders($partHeaders);
50
51 5
        $parts = $this->parseParts($stream, $partHeaders);
52
53 5
        if (!$message) {
54 5
            $message = new \Swift_Message ();
55 5
        }
56
57 5
        $headers = $this->createHeadersSet($filteredHeaders);
58
59 5
        foreach ($headers->getAll() as $name => $header) {
60
            if ($fillHeaders || in_array(strtolower($header->getFieldName()), $this->allowedHeaders)) {
61
                $message->getHeaders()->set($header);
62
            }
63 5
        }
64 5
        $this->createMessage($parts, $message);
65
66 5
        return $message;
67
    }
68
69 5
    protected function extractHeaders($stream)
70
    {
71 5
        $headers = array();
72 5
        $hName = null;
73 5
        while (!feof($stream)) {
74 5
            $row = fgets($stream);
75 5
            if ($row == "\r\n" || $row == "\n" || $row == "\r") {
76 5
                break;
77
            }
78 5
            if (preg_match('/^([a-z0-9\-]+)\s*:(.*)/i', $row, $mch)) {
79 5
                $hName = strtolower($mch [1]);
80 5
                if (!in_array($hName, array("content-type", "content-transfer-encoding"))) {
81 5
                    $hName = $mch [1];
82 5
                }
83 5
                $row = $mch [2];
84 5
            }
85 5
            if (!empty($hName)) {
86 5
                continue;
87
            }
88
            $headers [$hName] [] = trim($row);
89
        }
90 5
        foreach ($headers as $header => $values) {
91
            $headers [$header] = $this->headerDecoder->decode(trim(implode(" ", $values)));
92 5
        }
93 5
        return $headers;
94
    }
95
96 5
    private function filterHeaders(array $headers)
97
    {
98 5
        foreach ($headers as $header => $values) {
99
            if (in_array(strtolower($header), $this->removeHeaders) && !in_array(strtolower($header), $this->allowedHeaders)) {
100
                unset ($headers [$header]);
101
            }
102 5
        }
103 5
        return $headers;
104
    }
105
106 5
    protected function parseParts($stream, $partHeaders)
107
    {
108 5
        $parts = array();
109 5
        $contentType = $this->extractValueHeader($this->getContentType($partHeaders));
110
111 5
        if (stripos($contentType, 'multipart/') !== false) {
112
            $headerParts = $this->extractHeaderParts($this->getContentType($partHeaders));
113
            $boundary = $headerParts ["boundary"];
114
        } else {
115 5
            $boundary = null;
116
        }
117
118
        try {
119
            // body
120 5
            $this->extractPart($stream, $boundary, $this->getTransferEncoding($partHeaders));
121 5
        } catch (Exception\EndOfPartReachedException $e) {
122
            $parts = array(
123 5
                "type" => $contentType,
124 5
                "headers" => $partHeaders,
125 5
                "body" => $e->getData(),
126 5
                "boundary" => $boundary,
127 5
                "parts" => array()
128 5
            );
129
        }
130
131 5
        if ($boundary) {
132
            while (!feof($stream)) {
133
                try {
134
                    $partHeaders = $this->extractHeaders($stream);
135
                    $childContentType = $this->extractValueHeader($this->getContentType($partHeaders));
136
137
                    if (stripos($childContentType, 'multipart/') !== false) {
138
                        $parts ["parts"] [] = $this->parseParts($stream, $partHeaders);
139
                        try {
140
                            $this->extractPart($stream, $boundary, $this->getTransferEncoding($partHeaders));
141
                        } catch (Exception\EndOfPartReachedException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
142
                        }
143
                    } else {
144
                        $this->extractPart($stream, $boundary, $this->getTransferEncoding($partHeaders));
145
                    }
146
                } catch (Exception\EndOfPartReachedException $e) {
147
                    $parts ["parts"] [] = array(
148
                        "type" => $childContentType,
0 ignored issues
show
Bug introduced by
The variable $childContentType does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
149
                        "parent-type" => $contentType,
150
                        "headers" => $partHeaders,
151
                        "body" => $e->getData(),
152
                        "parts" => array()
153
                    );
154
155
                    if ($e instanceof Exception\EndOfMultiPartReachedException) {
156
                        break;
157
                    }
158
                }
159
            }
160
        }
161 5
        return $parts;
162
    }
163
164 5
    private function extractValueHeader($header)
165
    {
166 5
        $pos = stripos($header, ';');
167 5
        if ($pos !== false) {
168
            return substr($header, 0, $pos);
169
        } else {
170 5
            return $header;
171
        }
172
    }
173
174 5
    private function getContentType(array $partHeaders)
175
    {
176 5
        if (array_key_exists('content-type', $partHeaders)) {
177
            return $partHeaders['content-type'];
178
        }
179
180 5
        return '';
181
    }
182
183
    private function extractHeaderParts($header)
184
    {
185
        if (stripos($header, ';') !== false) {
186
187
            $parts = explode(";", $header);
188
            array_shift($parts);
189
            $p = array();
190
            foreach ($parts as $pv) {
191
                if (!trim($pv)) {
192
                    continue;
193
                }
194
                list ($k, $v) = explode("=", trim($pv), 2);
195
                $p [$k] = trim($v, '"');
196
            }
197
            return $p;
198
        } else {
199
            return array();
200
        }
201
    }
202 5
    protected function extractPart($stream, $boundary, $encoding)
203
    {
204 5
        $rows = array();
205 5
        while (!feof($stream)) {
206 5
            $row = fgets($stream);
207
208 5
            if ($boundary !== null) {
209 View Code Duplication
                if (strpos($row, "--$boundary--") === 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
210
                    throw new Exception\EndOfMultiPartReachedException ($this->contentDecoder->decode(implode("", $rows), $encoding));
211
                }
212 View Code Duplication
                if (strpos($row, "--$boundary") === 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
213
                    throw new Exception\EndOfPartReachedException ($this->contentDecoder->decode(implode("", $rows), $encoding));
214
                }
215
            }
216 5
            $rows [] = $row;
217 5
        }
218 5
        throw new Exception\EndOfMultiPartReachedException ($this->contentDecoder->decode(implode("", $rows), $encoding));
219
    }
220
221 5
    private function getTransferEncoding(array $partHeaders)
222
    {
223 5
        if (array_key_exists('content-transfer-encoding', $partHeaders)) {
224
            return $partHeaders ['content-transfer-encoding'];
225
        }
226
227 5
        return '';
228
    }
229
230
    /**
231
     *
232
     * @param array $headersRaw
233
     * @return \Swift_Mime_HeaderSet
234
     */
235 5
    protected function createHeadersSet(array $headersRaw)
236
    {
237 5
        $headers = \Swift_DependencyContainer::getInstance()->lookup('mime.headerset');
238
239 5
        foreach ($headersRaw as $name => $value) {
240
            switch (strtolower($name)) {
241
                case "content-type":
242
                    $parts = $this->extractHeaderParts($value);
243
                    unset ($parts ["boundary"]);
244
                    $headers->addParameterizedHeader($name, $this->extractValueHeader($value), $parts);
245
                    break;
246
                case "return-path" :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
247
                    if (preg_match_all('/([a-z][a-z0-9_\-\.]*@[a-z0-9\.\-]*\.[a-z]{2,5})/i', $value, $mch)) {
248
                        foreach ($mch [0] as $k => $mails) {
249
                            $headers->addPathHeader($name, $mch [1] [$k]);
250
                        }
251
                    }
252
                    break;
253
                case "date":
254
                    $headers->addDateHeader($name, strtotime($value));
255
                    break;
256
                case "to":
257
                case "from":
258
                case "bcc" :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
259
                case "reply-to":
260
                case "cc":
261
                    $adresses = array();
262
                    if (preg_match_all('/(.*?)<([a-z][a-z0-9_\-\.]*@[a-z0-9\.\-]*\.[a-z]{2,5})>\s*[;,]*/i', $value, $mch)) {
263
                        foreach ($mch [0] as $k => $mail) {
264
                            if (!$mch [1] [$k]) {
265
                                $adresses [$mch [2] [$k]] = trim($mch [2] [$k]);
266
                            } else {
267
                                $adresses [$mch [2] [$k]] = trim($mch [1] [$k]);
268
                            }
269
                        }
270
                    } elseif (preg_match_all('/([a-z][a-z0-9_\-\.]*@[a-z0-9\.\-]*\.[a-z]{2,5})/i', $value, $mch)) {
271
                        foreach ($mch [0] as $k => $mails) {
272
                            $adresses [$mch [1] [$k]] = trim($mch [1] [$k]);
273
                        }
274
                    }
275
                    $headers->addMailboxHeader($name, $adresses);
276
                    break;
277
                default:
278
                    $headers->addTextHeader($name, $value);
279
                    break;
280
            }
281 5
        }
282 5
        return $headers;
283
    }
284
285 5
    protected function createMessage(array $message, \Swift_Mime_MimeEntity $entity)
286
    {
287 5
        if (stripos($message ["type"], 'multipart/') !== false) {
288
289
            if (strpos($message ["type"], '/alternative')) {
290
                $nestingLevel = \Swift_Mime_MimeEntity::LEVEL_ALTERNATIVE;
291
            } elseif (strpos($message ["type"], '/related')) {
292
                $nestingLevel = \Swift_Mime_MimeEntity::LEVEL_RELATED;
293
            } elseif (strpos($message ["type"], '/mixed')) {
294
                $nestingLevel = \Swift_Mime_MimeEntity::LEVEL_MIXED;
295
            }
296
297
            $childrens = array();
298
            foreach ($message ["parts"] as $part) {
299
300
                $headers = $this->createHeadersSet($part ["headers"]);
301
                $encoder = $this->getEncoder($this->getTransferEncoding($part ["headers"]));
302
303
                if (stripos($part ["type"], 'multipart/') !== false) {
304
                    $newEntity = new \Swift_Mime_MimePart ($headers, $encoder, $this->cache, $this->grammar);
305
                } else {
306
                    $newEntity = new \Swift_Mime_SimpleMimeEntity ($headers, $encoder, $this->cache, $this->grammar);
307
                }
308
309
                $this->createMessage($part, $newEntity);
310
311
                $ref = new \ReflectionObject ($newEntity);
312
                $m = $ref->getMethod('_setNestingLevel');
313
                $m->setAccessible(true);
314
                $m->invoke($newEntity, $nestingLevel);
0 ignored issues
show
Bug introduced by
The variable $nestingLevel does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
315
316
                $childrens [] = $newEntity;
317
            }
318
319
            $entity->setContentType($part ["type"]);
0 ignored issues
show
Bug introduced by
The variable $part seems to be defined by a foreach iteration on line 298. Are you sure the iterator is never empty, otherwise this variable is not defined?

It seems like you are relying on a variable being defined by an iteration:

foreach ($a as $b) {
}

// $b is defined here only if $a has elements, for example if $a is array()
// then $b would not be defined here. To avoid that, we recommend to set a
// default value for $b.


// Better
$b = 0; // or whatever default makes sense in your context
foreach ($a as $b) {
}

// $b is now guaranteed to be defined here.
Loading history...
Bug introduced by
It seems like you code against a concrete implementation and not the interface Swift_Mime_MimeEntity as the method setContentType() does only exist in the following implementations of said interface: Swift_Attachment, Swift_EmbeddedFile, Swift_Image, Swift_Message, Swift_MimePart, Swift_Mime_Attachment, Swift_Mime_EmbeddedFile, Swift_Mime_MimePart, Swift_Mime_SimpleMessage, Swift_Mime_SimpleMimeEntity, Swift_SignedMessage.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
320
            $entity->setChildren($childrens);
321
        } else {
322 5
            $entity->setBody($message ["body"], $message ["type"]);
323
        }
324 5
    }
325
326
    /**
327
     *
328
     * @param string $type
329
     * @return \Swift_Mime_ContentEncoder
330
     */
331
    protected function getEncoder($type)
332
    {
333
        switch ($type) {
334
            case "base64" :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
335
                return \Swift_DependencyContainer::getInstance()->lookup('mime.base64contentencoder');
336
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
337
            case "8bit" :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
338
                return \Swift_DependencyContainer::getInstance()->lookup('mime.8bitcontentencoder');
339
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
340
            case "7bit" :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
341
                return \Swift_DependencyContainer::getInstance()->lookup('mime.7bitcontentencoder');
342
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
343
            default :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a DEFAULT statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in the default statement.

switch ($expr) {
    default : //wrong
        doSomething();
        break;
}

switch ($expr) {
    default: //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
344
                return \Swift_DependencyContainer::getInstance()->lookup('mime.qpcontentencoder');
345
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
346
        }
347
    }
348
349
    /**
350
     *
351
     * @param string $path
352
     *            The file containg a MIME message
353
     * @return \Swift_Message
354
     */
355 1
    public function parseFile($path, $fillHeaders = false, \Swift_Mime_MimeEntity $message = null)
356
    {
357 1
        $fp = fopen($path, "rb");
358 1
        $message = $this->parseStream($fp, $fillHeaders, $message);
0 ignored issues
show
Documentation introduced by
$fp is of type resource, but the function expects a object<Goetas\Mail\ToSwiftMailParser\stream>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
359 1
        fclose($fp);
360 1
        return $message;
361
    }
362
}
363