Test Failed
Push — 2.0 ( 3431b8...9e8731 )
by Zaahid
03:11
created

MultiPart::isMultiPart()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 6
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\Message;
8
9
use ZBateson\MailMimeParser\MailMimeParser;
10
use ZBateson\MailMimeParser\Message\PartStreamContainer;
11
use ZBateson\MailMimeParser\Message\PartFilter;
12
use Iterator;
13
use AppendIterator;
14
use ArrayIterator;
15
use RecursiveIteratorIterator;
16
17
/**
18
 * A message part that contains children.
19
 *
20
 * @author Zaahid Bateson
21
 */
22
abstract class MultiPart extends MessagePart implements IMultiPart
23
{
24
    /**
25
     * @var PartChildrenContainer child part container
26
     */
27
    protected $partChildrenContainer;
28
29
    public function __construct(
30
        IMimePart $parent = null,
31
        PartStreamContainer $streamContainer = null,
32
        PartChildrenContainer $partChildrenContainer = null
33
    ) {
34
        parent::__construct($streamContainer, $parent);
0 ignored issues
show
Bug introduced by
It seems like $streamContainer can also be of type null; however, parameter $streamContainer of ZBateson\MailMimeParser\...sagePart::__construct() does only seem to accept ZBateson\MailMimeParser\...age\PartStreamContainer, 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

34
        parent::__construct(/** @scrutinizer ignore-type */ $streamContainer, $parent);
Loading history...
35
        if ($partChildrenContainer === null) {
36
            $di = MailMimeParser::getDependencyContainer();
37
            $partChildrenContainer = $di['ZBateson\MailMimeParser\Message\PartChildrenContainer'];
38
        }
39
        $this->partChildrenContainer = $partChildrenContainer;
40
    }
41
42
    private function getAllPartsIterator()
43
    {
44
        $iter = new AppendIterator();
45
        $iter->append(new ArrayIterator([ $this ]));
46
        $iter->append(new RecursiveIteratorIterator($this->partChildrenContainer, RecursiveIteratorIterator::SELF_FIRST));
47
        return $iter;
48
    }
49
50
    private function iteratorFindAt(Iterator $iter, $index, $fnFilter = null)
51
    {
52
        $pos = 0;
53
        foreach ($iter as $part) {
54
            if (($fnFilter === null || $fnFilter($part))) {
55
                if ($index === $pos) {
56
                    return $part;
57
                }
58
                ++$pos;
59
            }
60
        }
61
    }
62
63
    public function getPart($index, $fnFilter = null)
64
    {
65
        return $this->iteratorFindAt(
66
            $this->getAllPartsIterator(),
67
            $index,
68
            $fnFilter
69
        );
70
    }
71
72
    public function getAllParts($fnFilter = null)
73
    {
74
        $array = iterator_to_array($this->getAllPartsIterator(), false);
75
        if ($fnFilter !== null) {
76
            return array_values(array_filter($array, $fnFilter));
77
        }
78
        return $array;
79
    }
80
81
    public function getPartCount($fnFilter = null)
82
    {
83
        return count($this->getAllParts($fnFilter));
84
    }
85
86
    public function getChild($index, $fnFilter = null)
87
    {
88
        return $this->iteratorFindAt(
89
            $this->partChildrenContainer,
90
            $index,
91
            $fnFilter
92
        );
93
    }
94
95
    public function getChildIterator()
96
    {
97
        return $this->partChildrenContainer;
98
    }
99
100
    public function getChildParts($fnFilter = null)
101
    {
102
        $array = iterator_to_array($this->partChildrenContainer, false);
103
        if ($fnFilter !== null) {
104
            return array_values(array_filter($array, $fnFilter));
105
        }
106
        return $array;
107
    }
108
109
    public function getChildCount($fnFilter = null)
110
    {
111
        return count($this->getChildParts($fnFilter));
112
    }
113
114
    public function getPartByMimeType($mimeType, $index = 0)
115
    {
116
        return $this->getPart($index, PartFilter::fromContentType($mimeType));
117
    }
118
119
    public function getAllPartsByMimeType($mimeType)
120
    {
121
        return $this->getAllParts(PartFilter::fromContentType($mimeType));
122
    }
123
124
    public function getCountOfPartsByMimeType($mimeType)
125
    {
126
        return $this->getPartCount(PartFilter::fromContentType($mimeType));
127
    }
128
129
    public function getPartByContentId($contentId)
130
    {
131
        $sanitized = preg_replace('/^\s*<|>\s*$/', '', $contentId);
132
        return $this->getPart(0, function (IMessagePart $part) use ($sanitized) {
133
            return strcasecmp($part->getContentId(), $sanitized) === 0;
0 ignored issues
show
Bug introduced by
It seems like $part->getContentId() can also be of type null; however, parameter $string1 of strcasecmp() does only seem to accept string, 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

133
            return strcasecmp(/** @scrutinizer ignore-type */ $part->getContentId(), $sanitized) === 0;
Loading history...
134
        });
135
    }
136
137
    public function addChild(IMessagePart $part, $position = null)
138
    {
139
        if ($part !== $this) {
0 ignored issues
show
introduced by
The condition $part !== $this is always true.
Loading history...
140
            $part->parent = $this;
0 ignored issues
show
Bug introduced by
Accessing parent on the interface ZBateson\MailMimeParser\Message\IMessagePart suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
141
            $this->partChildrenContainer->add($part, $position);
142
            $this->notify();
143
        }
144
    }
145
146
    public function removePart(IMessagePart $part)
147
    {
148
        $parent = $part->getParent();
149
        if ($this !== $parent && $parent !== null) {
150
            return $parent->removePart($part);
151
        } else {
152
            $position = $this->partChildrenContainer->remove($part);
153
            if ($position !== null) {
0 ignored issues
show
introduced by
The condition $position !== null is always true.
Loading history...
154
                $this->notify();
155
            }
156
            return $position;
157
        }
158
    }
159
160
    public function removeAllParts($fnFilter = null)
161
    {
162
        $parts = $this->getAllParts($fnFilter);
163
        $count = count($parts);
164
        foreach ($parts as $part) {
165
            if ($part === $this) {
166
                --$count;
167
                continue;
168
            }
169
            $this->removePart($part);
170
        }
171
        return $count;
172
    }
173
}
174