Passed
Push — master ( 2ea88e...404a7f )
by Zaahid
03:05
created

PartStreamRegistry::attachEncodingFilterToStream()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 17
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 17
ccs 0
cts 15
cp 0
rs 9.2
cc 4
eloc 14
nc 4
nop 2
crap 20
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 1
        }
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]);
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 1
        }
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
                stream_filter_append($handle, 'mailmimeparser-uudecode', STREAM_FILTER_READ);
122
                break;
123
            default:
124
                break;
125
        }
126
    }
127
    
128
    /**
129
     * Attaches a mailmimeparser-encode stream filter based on the part's
130
     * defined charset.
131
     * 
132
     * @param \ZBateson\MailMimeParser\Message\MimePart $part
133
     * @param resource $handle
134
     */
135
    private function attachCharsetFilterToStream(MimePart $part, $handle)
136
    {
137
        if ($part->isTextPart()) {
138
            stream_filter_append(
139
                $handle,
140
                'mailmimeparser-encode',
141
                STREAM_FILTER_READ,
142
                [ 'charset' => $part->getHeaderParameter('Content-Type', 'charset') ]
143
            );
144
        }
145
    }
146
147
    /**
148
     * Creates a part stream handle for the start and end position of the
149
     * message stream, and attaches it to the passed MimePart.
150
     * 
151
     * @param MimePart $part
152
     * @param Message $message
153
     * @param int $start
154
     * @param int $end
155
     */
156
    public function attachContentPartStreamHandle(MimePart $part, Message $message, $start, $end)
157
    {
158
        $id = $message->getObjectId();
159
        if (empty($this->registeredHandles[$id])) {
160
            return null;
161
        }
162
        $handle = fopen('mmp-mime-message://' . $id . '?start=' .
163
            $start . '&end=' . $end, 'r');
164
        
165
        $this->attachEncodingFilterToStream($part, $handle);
166
        $this->attachCharsetFilterToStream($part, $handle);
167
        $part->attachContentResourceHandle($handle);
168
    }
169
    
170
    /**
171
     * Creates a part stream handle for the start and end position of the
172
     * message stream, and attaches it to the passed MimePart.
173
     * 
174
     * @param MimePart $part
175
     * @param Message $message
176
     * @param int $start
177
     * @param int $end
178
     */
179
    public function attachOriginalPartStreamHandle(MimePart $part, Message $message, $start, $end)
180
    {
181
        $id = $message->getObjectId();
182
        if (empty($this->registeredHandles[$id])) {
183
            return null;
184
        }
185
        $handle = fopen('mmp-mime-message://' . $id . '?start=' .
186
            $start . '&end=' . $end, 'r');
187
        
188
        $part->attachOriginalStreamHandle($handle);
189
    }
190
}
191