Completed
Push — master ( 322b29...4152da )
by Malte
03:58
created

Attachment::getExtension()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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

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