Upload   A
last analyzed

Complexity

Total Complexity 24

Size/Duplication

Total Lines 206
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 52
dl 0
loc 206
rs 10
c 2
b 0
f 0
wmc 24

11 Methods

Rating   Name   Duplication   Size   Complexity  
A addDefaultValidations() 0 4 1
A addValidations() 0 5 1
A getInfo() 0 3 1
A process() 0 21 5
A isValid() 0 7 2
A isUploaded() 0 3 1
A getErrors() 0 3 1
A setFilename() 0 7 2
A addValidation() 0 5 1
A __construct() 0 32 6
A validateFile() 0 6 3
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
 *
13
 * @author      Josh Lockhart <[email protected]>
14
 * @copyright   2012 Josh Lockhart
15
 * @link        http://www.joshlockhart.com
16
 * @version     2.0.0
17
 *
18
 * Permission is hereby granted, free of charge, to any person obtaining a copy
19
 * of this software and associated documentation files (the "Software"), to deal
20
 * in the Software without restriction, including without limitation the rights
21
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
22
 * copies of the Software, and to permit persons to whom the Software is
23
 * furnished to do so, subject to the following conditions:
24
 *
25
 * The above copyright notice and this permission notice shall be included in all
26
 * copies or substantial portions of the Software.
27
 *
28
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
29
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
30
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
31
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
32
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
33
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
34
 * SOFTWARE.
35
 */
36
37
/**
38
 *  @file Upload.php
39
 *
40
 *  The main Upload class
41
 *
42
 *  @package    Platine\Upload
43
 *  @author Platine Developers Team
44
 *  @copyright  Copyright (c) 2020
45
 *  @license    http://opensource.org/licenses/MIT  MIT License
46
 *  @link   https://www.platine-php.com
47
 *  @version 1.0.0
48
 *  @filesource
49
 */
50
51
declare(strict_types=1);
52
53
namespace Platine\Upload;
54
55
use Platine\Http\UploadedFile;
56
use Platine\Upload\File\File;
57
use Platine\Upload\File\UploadFileInfo;
58
use Platine\Upload\Storage\StorageInterface;
59
use Platine\Upload\Util\Helper;
60
use Platine\Upload\Validator\Rule\UploadError;
61
use Platine\Upload\Validator\RuleInterface;
62
use Platine\Upload\Validator\Validator;
63
use RuntimeException;
64
65
/**
66
 * @class Upload
67
 * @package Platine\Upload
68
 */
69
class Upload
70
{
71
    /**
72
     * Upload Storage
73
     * @var StorageInterface
74
     */
75
    protected StorageInterface $storage;
76
77
    /**
78
     * The upload validation object
79
     * @var Validator
80
     */
81
    protected Validator $validator;
82
83
    /**
84
     * The list of uploaded file
85
     * @var File[]
86
     */
87
    protected array $files = [];
88
89
    /**
90
     * The validations errors messages
91
     * @var array<int, string>
92
     */
93
    protected array $errors = [];
94
95
    /**
96
     * Set custom file name
97
     * @var string
98
     */
99
    protected string $filename;
100
101
    /**
102
     * The uploaded file information
103
     * @var UploadFileInfo|UploadFileInfo[]|bool
104
     */
105
    protected UploadFileInfo|array|bool $uploadInfo = false;
106
107
    /**
108
     * Create new instance
109
     * @param string $key the file key to use
110
     * @param StorageInterface $storage
111
     * @param Validator|null $validator
112
     * @param array<mixed> $uploadedFiles
113
     */
114
    public function __construct(
115
        string $key,
116
        StorageInterface $storage,
117
        ?Validator $validator = null,
118
        array $uploadedFiles = []
119
    ) {
120
        if ((bool) ini_get('file_uploads') === false) {
121
            throw new RuntimeException('File uploads are disabled in your PHP.ini file');
122
        }
123
124
        $this->storage = $storage;
125
        $this->validator = $validator ?? new Validator();
126
127
        if (count($uploadedFiles) === 0) {
128
            $uploadedFiles = UploadedFile::createFromGlobals();
129
        }
130
131
        $files = Helper::normalizeFiles($uploadedFiles);
132
133
        if (array_key_exists($key, $files)) {
134
            $fileInfo = $files[$key];
135
            if (is_array($fileInfo)) {
136
                foreach ($fileInfo as $file) {
137
                    $this->files[] = $file;
138
                }
139
            } else {
140
                $this->files[] = $fileInfo;
141
            }
142
        }
143
144
        //add default validation rule
145
        $this->addDefaultValidations();
146
    }
147
148
    /**
149
    * Whether the file is uploaded
150
    */
151
    public function isUploaded(): bool
152
    {
153
        return count($this->files) > 0;
154
    }
155
156
    /**
157
     * Set custom filename
158
     * @param string $name
159
     * @return $this
160
     */
161
    public function setFilename(string $name): self
162
    {
163
        foreach ($this->files as $file) {
164
            $file->setName($name);
165
        }
166
167
        return $this;
168
    }
169
170
    /**
171
     * Shortcut to Validator::addRule
172
     * @param RuleInterface $rule
173
     * @return $this
174
     */
175
    public function addValidation(RuleInterface $rule): self
176
    {
177
        $this->validator->addRule($rule);
178
179
        return $this;
180
    }
181
182
    /**
183
     * Add validations array
184
     * @param RuleInterface[] $rules
185
     * @return $this
186
     */
187
    public function addValidations(array $rules): self
188
    {
189
        $this->validator->addRules($rules);
190
191
        return $this;
192
    }
193
194
    /**
195
     * Check whether the file to upload is valid
196
     * @return bool
197
     */
198
    public function isValid(): bool
199
    {
200
        foreach ($this->files as $file) {
201
            $this->validateFile($file);
202
        }
203
204
        return count($this->errors) === 0;
205
    }
206
207
    /**
208
     * Process upload
209
     * @return bool
210
     */
211
    public function process(): bool
212
    {
213
        if ($this->isValid() === false) {
214
            return false;
215
        }
216
217
        $result = [];
218
219
        foreach ($this->files as $file) {
220
            if ($file->getError() === UPLOAD_ERR_OK) {
221
                $result[] = $this->storage->upload($file);
222
            }
223
        }
224
225
        if (count($result) === 1) {
226
            $this->uploadInfo = $result[0];
227
        } else {
228
            $this->uploadInfo = $result;
229
        }
230
231
        return true;
232
    }
233
234
    /**
235
     * Return the validation errors
236
     * @return array<int, string>
237
     */
238
    public function getErrors(): array
239
    {
240
        return $this->errors;
241
    }
242
243
    /**
244
     * Return the uploaded file information
245
     * @return UploadFileInfo|UploadFileInfo[]|bool
246
     */
247
    public function getInfo(): UploadFileInfo|array|bool
248
    {
249
        return $this->uploadInfo;
250
    }
251
252
    /**
253
     * Validate the uploaded file
254
     * @param File $file
255
     * return void
256
     */
257
    protected function validateFile(File $file): void
258
    {
259
        foreach ($this->validator->getRules() as $rule) {
260
            if ($rule->validate($file) === false) {
261
                $this->errors[] = $rule->getErrorMessage($file);
262
                break;
263
            }
264
        }
265
    }
266
267
    /**
268
     * Add default rules validations
269
     * @return void
270
     */
271
    protected function addDefaultValidations(): void
272
    {
273
        $this->validator->addRules([
274
            new UploadError()
275
        ]);
276
    }
277
}
278