Passed
Push — master ( 42c825...47f6d8 )
by Malte
02:48
created

Attachment::fetch()   D

Complexity

Conditions 14
Paths 300

Size

Total Lines 41
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 14
eloc 24
nc 300
nop 0
dl 0
loc 41
rs 4.1833
c 0
b 0
f 0

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
* File:     Attachment.php
4
* Category: -
5
* Author:   M. Goldenbaum
6
* Created:  16.03.18 19:37
7
* Updated:  -
8
*
9
* Description:
10
*  -
11
*/
12
13
namespace Webklex\IMAP;
14
15
use Illuminate\Support\Facades\File;
16
use Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesser;
17
18
/**
19
 * Class Attachment
20
 *
21
 * @package Webklex\IMAP
22
 */
23
class Attachment {
24
25
    /** @var Message $oMessage */
26
    protected $oMessage;
27
28
    /** @var object $structure */
29
    protected $structure;
30
31
    /** @var int $part_number */
32
    protected $part_number = 1;
33
34
    /** @var null|string $content */
35
    public $content = null;
36
37
    /** @var null|string $type */
38
    public $type = null;
39
40
    /** @var null|string $content_type */
41
    public $content_type = null;
42
43
    /** @var null|string $id */
44
    public $id = null;
45
46
    /** @var null|string $name */
47
    public $name = null;
48
49
    /** @var null|string $disposition */
50
    public $disposition = null;
51
52
    /** @var null|string $img_src */
53
    public $img_src = null;
54
55
    /**
56
     * Attachment const
57
     *
58
     * @const integer   TYPE_TEXT
59
     * @const integer   TYPE_MULTIPART
60
     * @const integer   TYPE_MESSAGE
61
     * @const integer   TYPE_APPLICATION
62
     * @const integer   TYPE_AUDIO
63
     * @const integer   TYPE_IMAGE
64
     * @const integer   TYPE_VIDEO
65
     * @const integer   TYPE_MODEL
66
     * @const integer   TYPE_OTHER
67
     */
68
    const TYPE_TEXT = 0;
69
    const TYPE_MULTIPART = 1;
70
    const TYPE_MESSAGE = 2;
71
    const TYPE_APPLICATION = 3;
72
    const TYPE_AUDIO = 4;
73
    const TYPE_IMAGE = 5;
74
    const TYPE_VIDEO = 6;
75
    const TYPE_MODEL = 7;
76
    const TYPE_OTHER = 8;
77
78
    /**
79
     * Attachment constructor.
80
     *
81
     * @param Message   $oMessage
82
     * @param object    $structure
83
     * @param integer   $part_number
84
     */
85
    public function __construct(Message $oMessage, $structure, $part_number = 1) {
86
        $this->oMessage = $oMessage;
87
        $this->structure = $structure;
88
        $this->part_number = ($part_number) ? $part_number : $this->part_number;
89
90
        $this->findType();
91
        $this->fetch();
92
    }
93
94
    /**
95
     * Determine the structure type
96
     */
97
    protected function findType() {
98
        switch ($this->structure->type) {
99
            case self::TYPE_MESSAGE:
100
                $this->type = 'message';
101
                break;
102
            case self::TYPE_APPLICATION:
103
                $this->type = 'application';
104
                break;
105
            case self::TYPE_AUDIO:
106
                $this->type = 'audio';
107
                break;
108
            case self::TYPE_IMAGE:
109
                $this->type = 'image';
110
                break;
111
            case self::TYPE_VIDEO:
112
                $this->type = 'video';
113
                break;
114
            case self::TYPE_MODEL:
115
                $this->type = 'model';
116
                break;
117
            case self::TYPE_TEXT:
118
                $this->type = 'text';
119
                break;
120
            case self::TYPE_MULTIPART:
121
                $this->type = 'multipart';
122
                break;
123
            default:
124
                $this->type = 'other';
125
                break;
126
        }
127
    }
128
129
    /**
130
     * Fetch the given attachment
131
     */
132
    protected function fetch() {
133
134
        $content = imap_fetchbody($this->oMessage->getClient()->getConnection(), $this->oMessage->getUid(), $this->part_number, $this->oMessage->getFetchOptions() | FT_UID);
0 ignored issues
show
Bug introduced by
It seems like $this->oMessage->getClient()->getConnection() can also be of type true; however, parameter $imap_stream of imap_fetchbody() 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

134
        $content = imap_fetchbody(/** @scrutinizer ignore-type */ $this->oMessage->getClient()->getConnection(), $this->oMessage->getUid(), $this->part_number, $this->oMessage->getFetchOptions() | FT_UID);
Loading history...
135
136
        $this->content_type = $this->type.'/'.strtolower($this->structure->subtype);
137
        $this->content = $this->oMessage->decodeString($content, $this->structure->encoding);
138
139
        if (property_exists($this->structure, 'id')) {
140
            $this->id = str_replace(['<', '>'], '', $this->structure->id);
141
        }
142
143
        if (property_exists($this->structure, 'dparameters')) {
144
            foreach ($this->structure->dparameters as $parameter) {
145
                if (strtolower($parameter->attribute) == "filename") {
146
                    $this->setName($parameter->value);
147
                    $this->disposition = property_exists($this->structure, 'disposition') ? $this->structure->disposition : null;
148
                    break;
149
                }
150
            }
151
        }
152
153
        if (self::TYPE_MESSAGE == $this->structure->type) {
154
            if ($this->structure->ifdescription) {
155
                $this->setName($this->structure->description);
156
            } else {
157
                $this->setName($this->structure->subtype);
158
            }
159
        }
160
161
        if (!$this->name && property_exists($this->structure, 'parameters')) {
162
            foreach ($this->structure->parameters as $parameter) {
163
                if (strtolower($parameter->attribute) == "name") {
164
                    $this->setName($parameter->value);
165
                    $this->disposition = property_exists($this->structure, 'disposition') ? $this->structure->disposition : null;
166
                    break;
167
                }
168
            }
169
        }
170
171
        if ($this->type == 'image') {
172
            $this->img_src = 'data:'.$this->content_type.';base64,'.base64_encode($this->content);
173
        }
174
    }
175
176
    /**
177
     * Save the attachment content to your filesystem
178
     *
179
     * @param string|null $path
180
     * @param string|null $filename
181
     *
182
     * @return boolean
183
     */
184
    public function save($path = null, $filename = null) {
185
        $path = $path ?: storage_path();
186
        $filename = $filename ?: $this->getName();
187
188
        $path = substr($path, -1) == DIRECTORY_SEPARATOR ? $path : $path.DIRECTORY_SEPARATOR;
189
190
        return File::put($path.$filename, $this->getContent()) !== false;
191
    }
192
193
    /**
194
     * @return null|string
195
     */
196
    public function getContent() {
197
        return $this->content;
198
    }
199
200
    /**
201
     * @return null|string
202
     */
203
    public function getType() {
204
        return $this->type;
205
    }
206
207
    /**
208
     * @return null|string
209
     */
210
    public function getContentType() {
211
        return $this->content_type;
212
    }
213
214
    /**
215
     * @return null|string
216
     */
217
    public function getId() {
218
        return $this->id;
219
    }
220
221
    /**
222
     * @param $name
223
     */
224
    public function setName($name) {
225
        $this->name = $this->oMessage->decodeString($this->oMessage->convertEncoding($name, $this->oMessage->getEncoding($name)), 'UTF-7');
226
    }
227
228
    /**
229
     * @return null|string
230
     */
231
    public function getName() {
232
        return $this->name;
233
    }
234
235
    /**
236
     * @return null|string
237
     */
238
    public function getDisposition() {
239
        return $this->disposition;
240
    }
241
242
    /**
243
     * @return null|string
244
     */
245
    public function getImgSrc() {
246
        return $this->img_src;
247
    }
248
249
    /**
250
     * @return string|null
251
     */
252
    public function getMimeType(){
253
        return (new \finfo())->buffer($this->getContent(), FILEINFO_MIME_TYPE);
254
    }
255
256
    /**
257
     * @return string|null
258
     */
259
    public function getExtension(){
260
        return ExtensionGuesser::getInstance()->guess($this->getMimeType());
261
    }
262
}