Passed
Push — develop ( d0a329...633762 )
by nguereza
09:02
created

File::getMimeType()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 9
nc 4
nop 0
dl 0
loc 15
rs 9.9666
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Platine Upload
5
 *
6
 * Platine Upload provides a flexible file uploads with extensible
7
 * validation and storage strategies.
8
 *
9
 * This content is released under the MIT License (MIT)
10
 *
11
 * Copyright (c) 2020 Platine Upload
12
 * Copyright (c) 2014 Adrian Miu
13
 *
14
 * Permission is hereby granted, free of charge, to any person obtaining a copy
15
 * of this software and associated documentation files (the "Software"), to deal
16
 * in the Software without restriction, including without limitation the rights
17
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18
 * copies of the Software, and to permit persons to whom the Software is
19
 * furnished to do so, subject to the following conditions:
20
 *
21
 * The above copyright notice and this permission notice shall be included in all
22
 * copies or substantial portions of the Software.
23
 *
24
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
 * SOFTWARE.
31
 */
32
33
/**
34
 *  @file File.php
35
 *
36
 *  The Upload File class
37
 *
38
 *  @package    Platine\Upload\File
39
 *  @author Platine Developers Team
40
 *  @copyright  Copyright (c) 2020
41
 *  @license    http://opensource.org/licenses/MIT  MIT License
42
 *  @link   http://www.iacademy.cf
43
 *  @version 1.0.0
44
 *  @filesource
45
 */
46
47
declare(strict_types=1);
48
49
namespace Platine\Upload\File;
50
51
use finfo;
52
use InvalidArgumentException;
53
use RuntimeException;
54
use SplFileInfo;
55
56
/**
57
 * Class File
58
 * @package Platine\Upload\File
59
 */
60
class File extends SplFileInfo implements FileInterface
61
{
62
    /**
63
     * Factory used to create new instance
64
     * @var callable
65
     */
66
    protected static $factory = null;
67
68
    /**
69
     * The file name
70
     * @var string
71
     */
72
    protected string $name;
73
74
    /**
75
     * The file extension
76
     * @var string
77
     */
78
    protected string $extension;
79
80
    /**
81
     * The file mime type
82
     * @var string
83
     */
84
    protected string $mimeType = '';
85
86
    /**
87
     * The upload status
88
     * @var int
89
     */
90
    protected int $error = UPLOAD_ERR_OK;
91
92
93
    /**
94
     * Create new instance
95
     * @param string $filePath the file absolute path
96
     * @param string|null $name the desired new name
97
     * @param int $error
98
     */
99
    public function __construct(
100
        string $filePath,
101
        ?string $name = null,
102
        int $error = UPLOAD_ERR_OK
103
    ) {
104
        $this->error = $error;
105
106
        $newName = $name === null ? $filePath : $name;
107
108
        $this->setName(pathinfo($newName, PATHINFO_FILENAME));
0 ignored issues
show
Bug introduced by
It seems like pathinfo($newName, Plati...File\PATHINFO_FILENAME) can also be of type array; however, parameter $name of Platine\Upload\File\File::setName() 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

108
        $this->setName(/** @scrutinizer ignore-type */ pathinfo($newName, PATHINFO_FILENAME));
Loading history...
109
        $this->setExtension(pathinfo($newName, PATHINFO_EXTENSION));
0 ignored issues
show
Bug introduced by
It seems like pathinfo($newName, Plati...ile\PATHINFO_EXTENSION) can also be of type array; however, parameter $name of Platine\Upload\File\File::setExtension() 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

109
        $this->setExtension(/** @scrutinizer ignore-type */ pathinfo($newName, PATHINFO_EXTENSION));
Loading history...
110
111
        parent::__construct($filePath);
112
    }
113
114
    /**
115
    * {@inheritdoc}
116
    */
117
    public function getExtension(): string
118
    {
119
        return $this->extension;
120
    }
121
122
    /**
123
    * {@inheritdoc}
124
    */
125
    public function setExtension(string $name): self
126
    {
127
        $this->extension = strtolower($name);
128
129
        return $this;
130
    }
131
132
    /**
133
    * {@inheritdoc}
134
    */
135
    public function getFullName(): string
136
    {
137
        return $this->extension === '' ?
138
                $this->name
139
                : sprintf('%s.%s', $this->name, $this->extension);
140
    }
141
142
    /**
143
    * {@inheritdoc}
144
    */
145
    public function getMD5(): string
146
    {
147
        $hash = md5_file($this->getPathname());
148
        return $hash === false ? '' : $hash;
149
    }
150
151
    /**
152
    * {@inheritdoc}
153
    */
154
    public function getPathname(): string
155
    {
156
        return parent::getPathname();
157
    }
158
159
    /**
160
    * {@inheritdoc}
161
    */
162
    public function getSize(): int
163
    {
164
        return parent::getSize();
165
    }
166
167
    /**
168
    * {@inheritdoc}
169
    */
170
    public function getMimeType(): string
171
    {
172
        if (empty($this->mimeType)) {
173
            $finfo = new finfo(FILEINFO_MIME);
174
            $mimeType = $finfo->file($this->getPathname());
175
            if ($mimeType !== false) {
176
                $mimetypeParts = preg_split('/\s*[;,]\s*/', $mimeType);
177
                if (is_array($mimetypeParts)) {
0 ignored issues
show
introduced by
The condition is_array($mimetypeParts) is always true.
Loading history...
178
                    $this->mimeType = strtolower($mimetypeParts[0]);
179
                }
180
            }
181
            unset($finfo);
182
        }
183
184
        return $this->mimeType;
185
    }
186
187
    /**
188
    * {@inheritdoc}
189
    */
190
    public function getName(): string
191
    {
192
        return $this->name;
193
    }
194
195
    /**
196
    * {@inheritdoc}
197
    */
198
    public function setName(string $name): self
199
    {
200
        $cleanName = preg_replace('/[^A-Za-z0-9\.]+/', '_', $name);
201
        if ($cleanName !== null) {
202
            $filename = basename($cleanName);
203
            $this->name = $filename;
204
        }
205
206
        return $this;
207
    }
208
209
    /**
210
    * {@inheritdoc}
211
    */
212
    public function getError(): int
213
    {
214
        return $this->error;
215
    }
216
217
    /**
218
     * Set the factory used to create new instance
219
     * @param callable $callable
220
     * @return void
221
     * @throws InvalidArgumentException
222
     */
223
    public static function setFactory($callable): void
224
    {
225
        if (!is_callable($callable)) {
226
            throw new InvalidArgumentException('Factory is not a valid callback.');
227
        }
228
229
        static::$factory = $callable;
230
    }
231
232
    /**
233
     * Create new instance of this class
234
     * @param string $tmpName
235
     * @param string|null $name
236
     * @param int $error
237
     * @return self
238
     */
239
    public static function create(
240
        string $tmpName,
241
        ?string $name = null,
242
        int $error = UPLOAD_ERR_OK
243
    ): self {
244
        if (static::$factory !== null) {
0 ignored issues
show
introduced by
The condition static::factory !== null is always true.
Loading history...
245
            $file = call_user_func_array(static::$factory, [$tmpName, $name, $error]);
246
247
            if (!$file instanceof File) {
248
                throw new RuntimeException(sprintf(
249
                    'The File factory must return an instance of [%s]',
250
                    File::class
251
                ));
252
            }
253
254
            return $file;
255
        }
256
257
        return new self($tmpName, $name, $error);
258
    }
259
}
260