Passed
Push — 0.4 ( 016b60...90706e )
by Zaahid
04:27
created

PartStreamRegistry   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 168
Duplicated Lines 0 %

Test Coverage

Coverage 33.33%

Importance

Changes 0
Metric Value
wmc 21
eloc 51
dl 0
loc 168
ccs 21
cts 63
cp 0.3333
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A unregister() 0 4 1
A increaseHandleRefCount() 0 3 1
A register() 0 5 2
A get() 0 6 2
A attachCharsetFilterToStream() 0 8 2
A attachContentPartStreamHandle() 0 12 2
A attachOriginalPartStreamHandle() 0 10 2
A decreaseHandleRefCount() 0 5 2
B attachEncodingFilterToStream() 0 18 7
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\Stream;
8
9
use ZBateson\MailMimeParser\Message\MimePart;
10
use ZBateson\MailMimeParser\Message;
11
12
/**
13
 * Factory class for PartStream objects and registration class for Message
14
 * handles.
15
 * 
16
 * PartStreamRegistry is used for \ZBateson\MailMimeParser\Message\MessageParser to
17
 * register Message stream handles for opening with PartStreams, and to open
18
 * file handles for specific mime parts of a message.  The PartStreamRegistry
19
 * maintains a list of opened resources, closing them either when unregistering
20
 * a Message or on destruction.
21
 *
22
 * @author Zaahid Bateson
23
 */
24
class PartStreamRegistry
25
{
26
    /**
27
     * @var array Array of handles, with message IDs as keys.
28
     */
29
    private $registeredHandles;
30
    
31
    /**
32
     * @var int[] number of registered part stream handles with message IDs as
33
     * keys
34
     */
35
    private $numRefCountsForHandles;
36
37
    /**
38
     * Registers an ID for the passed resource handle.
39
     * 
40
     * @param string $id
41
     * @param resource $handle
42
     */
43 1
    public function register($id, $handle)
44
    {
45 1
        if (!isset($this->registeredHandles[$id])) {
46 1
            $this->registeredHandles[$id] = $handle;
47 1
            $this->numRefCountsForHandles[$id] = 0;
48
        }
49 1
    }
50
51
    /**
52
     * Unregisters the given message ID and closes the associated resource
53
     * handle.
54
     * 
55
     * @param string $id
56
     */
57 1
    protected function unregister($id)
58
    {
59 1
        fclose($this->registeredHandles[$id]);
60 1
        unset($this->registeredHandles[$id], $this->registeredPartStreamHandles[$id]);
0 ignored issues
show
Bug Best Practice introduced by
The property registeredPartStreamHandles does not exist on ZBateson\MailMimeParser\Stream\PartStreamRegistry. Did you maybe forget to declare it?
Loading history...
61 1
    }
62
    
63
    /**
64
     * Increases the reference count for streams using the resource handle
65
     * associated with the message id.
66
     * 
67
     * @param int $messageId
68
     */
69 1
    public function increaseHandleRefCount($messageId)
70
    {
71 1
        $this->numRefCountsForHandles[$messageId] += 1;
72 1
    }
73
    
74
    /**
75
     * Decreases the reference count for streams using the resource handle
76
     * associated with the message id.  Once the reference count hits 0,
77
     * unregister is called.
78
     * 
79
     * @param int $messageId
80
     */
81 1
    public function decreaseHandleRefCount($messageId)
82
    {
83 1
        $this->numRefCountsForHandles[$messageId] -= 1;
84 1
        if ($this->numRefCountsForHandles[$messageId] === 0) {
85 1
            $this->unregister($messageId);
86
        }
87 1
    }
88
89
    /**
90
     * Returns the resource handle with the passed $id.
91
     * 
92
     * @param string $id
93
     * @return resource
94
     */
95 1
    public function get($id)
96
    {
97 1
        if (!isset($this->registeredHandles[$id])) {
98 1
            return null;
99
        }
100 1
        return $this->registeredHandles[$id];
101
    }
102
    
103
    /**
104
     * Attaches a stream filter on the passed resource $handle for the part's
105
     * encoding.
106
     * 
107
     * @param \ZBateson\MailMimeParser\Message\MimePart $part
108
     * @param resource $handle
109
     */
110
    private function attachEncodingFilterToStream(MimePart $part, $handle)
111
    {
112
        $encoding = strtolower($part->getHeaderValue('Content-Transfer-Encoding'));
113
        switch ($encoding) {
114
            case 'quoted-printable':
115
                stream_filter_append($handle, 'mmp-convert.quoted-printable-decode', STREAM_FILTER_READ);
116
                break;
117
            case 'base64':
118
                stream_filter_append($handle, 'mmp-convert.base64-decode', STREAM_FILTER_READ);
119
                break;
120
            case 'x-uuencode':
121
            case 'x-uue':
122
            case 'uuencode':
123
            case 'uue':
124
                stream_filter_append($handle, 'mailmimeparser-uudecode', STREAM_FILTER_READ);
125
                break;
126
            default:
127
                break;
128
        }
129
    }
130
    
131
    /**
132
     * Attaches a mailmimeparser-encode stream filter based on the part's
133
     * defined charset.
134
     * 
135
     * @param \ZBateson\MailMimeParser\Message\MimePart $part
136
     * @param resource $handle
137
     */
138
    private function attachCharsetFilterToStream(MimePart $part, $handle)
139
    {
140
        if ($part->isTextPart()) {
141
            stream_filter_append(
142
                $handle,
143
                'mailmimeparser-encode',
144
                STREAM_FILTER_READ,
145
                [ 'charset' => $part->getHeaderParameter('Content-Type', 'charset') ]
146
            );
147
        }
148
    }
149
150
    /**
151
     * Creates a part stream handle for the start and end position of the
152
     * message stream, and attaches it to the passed MimePart.
153
     * 
154
     * @param MimePart $part
155
     * @param Message $message
156
     * @param int $start
157
     * @param int $end
158
     */
159
    public function attachContentPartStreamHandle(MimePart $part, Message $message, $start, $end)
160
    {
161
        $id = $message->getObjectId();
162
        if (empty($this->registeredHandles[$id])) {
163
            return null;
164
        }
165
        $handle = fopen('mmp-mime-message://' . $id . '?start=' .
166
            $start . '&end=' . $end, 'r');
167
        
168
        $this->attachEncodingFilterToStream($part, $handle);
0 ignored issues
show
Bug introduced by
It seems like $handle can also be of type false; however, parameter $handle of ZBateson\MailMimeParser\...ncodingFilterToStream() does only seem to accept resource, 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

168
        $this->attachEncodingFilterToStream($part, /** @scrutinizer ignore-type */ $handle);
Loading history...
169
        $this->attachCharsetFilterToStream($part, $handle);
0 ignored issues
show
Bug introduced by
It seems like $handle can also be of type false; however, parameter $handle of ZBateson\MailMimeParser\...CharsetFilterToStream() does only seem to accept resource, 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

169
        $this->attachCharsetFilterToStream($part, /** @scrutinizer ignore-type */ $handle);
Loading history...
170
        $part->attachContentResourceHandle($handle);
0 ignored issues
show
Bug introduced by
It seems like $handle can also be of type false; however, parameter $contentHandle of ZBateson\MailMimeParser\...ContentResourceHandle() does only seem to accept resource, 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

170
        $part->attachContentResourceHandle(/** @scrutinizer ignore-type */ $handle);
Loading history...
171
    }
172
    
173
    /**
174
     * Creates a part stream handle for the start and end position of the
175
     * message stream, and attaches it to the passed MimePart.
176
     * 
177
     * @param MimePart $part
178
     * @param Message $message
179
     * @param int $start
180
     * @param int $end
181
     */
182
    public function attachOriginalPartStreamHandle(MimePart $part, Message $message, $start, $end)
183
    {
184
        $id = $message->getObjectId();
185
        if (empty($this->registeredHandles[$id])) {
186
            return null;
187
        }
188
        $handle = fopen('mmp-mime-message://' . $id . '?start=' .
189
            $start . '&end=' . $end, 'r');
190
        
191
        $part->attachOriginalStreamHandle($handle);
0 ignored issues
show
Bug introduced by
It seems like $handle can also be of type false; however, parameter $handle of ZBateson\MailMimeParser\...hOriginalStreamHandle() does only seem to accept resource, 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

191
        $part->attachOriginalStreamHandle(/** @scrutinizer ignore-type */ $handle);
Loading history...
192
    }
193
}
194