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

Upload::getInfo()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
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 Upload.php
35
 *
36
 *  The main Upload class
37
 *
38
 *  @package    Platine\Upload
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;
50
51
use Platine\Http\UploadedFile;
52
use Platine\Upload\File\File;
53
use Platine\Upload\File\UploadFileInfo;
54
use Platine\Upload\Storage\StorageInterface;
55
use Platine\Upload\Util\Helper;
56
use Platine\Upload\Validator\Rule\UploadError;
57
use Platine\Upload\Validator\RuleInterface;
58
use Platine\Upload\Validator\Validator;
59
use RuntimeException;
60
61
/**
62
 * Class Upload
63
 * @package Platine\Upload
64
 */
65
class Upload
66
{
67
68
    /**
69
     * Upload Storage
70
     * @var StorageInterface
71
     */
72
    protected StorageInterface $storage;
73
74
    /**
75
     * The upload validation object
76
     * @var Validator
77
     */
78
    protected Validator $validator;
79
80
    /**
81
     * The list of uploaded file
82
     * @var array<int, File>
83
     */
84
    protected array $files = [];
85
86
    /**
87
     * The validations errors messages
88
     * @var array<int, string>
89
     */
90
    protected array $errors = [];
91
92
    /**
93
     * Set custom file name
94
     * @var string
95
     */
96
    protected string $filename;
97
98
99
    /**
100
     * The uploaded file information
101
     * @var UploadFileInfo|array<int, UploadFileInfo>|bool
102
     */
103
    protected $uploadInfo = false;
104
105
106
    /**
107
     * Create new instance
108
     * @param string $key the file key to use
109
     * @param StorageInterface $storage
110
     * @param Validator|null $validator
111
     */
112
    public function __construct(
113
        string $key,
114
        StorageInterface $storage,
115
        ?Validator $validator = null
116
    ) {
117
        // Check if file uploads are allowed
118
        if ((bool)ini_get('file_uploads') === false) {
119
            throw new RuntimeException('File uploads are disabled in your PHP.ini file');
120
        }
121
122
        $this->storage = $storage;
123
        $this->validator = $validator ? $validator : new Validator();
124
125
        $uploadedFiles = UploadedFile::createFromGlobals();
126
127
        $files = Helper::normalizeFiles($uploadedFiles);
128
129
        if (array_key_exists($key, $files)) {
130
            $fileInfo = $files[$key];
131
            if (is_array($fileInfo)) {
132
                foreach ($fileInfo as $file) {
133
                    $this->files[] = $file;
134
                }
135
            } else {
136
                $this->files[] = $fileInfo;
137
            }
138
        }
139
140
        //add default validation rule
141
        $this->addDefaultValidations();
142
    }
143
144
    /**
145
     * Set custom filename
146
     * @param string $name
147
     * @return $this
148
     */
149
    public function setFilename(string $name): self
150
    {
151
        foreach ($this->files as $file) {
152
            $file->setName($name);
153
        }
154
155
        return $this;
156
    }
157
158
    /**
159
     * Shortcut to Validator::addRule
160
     * @param RuleInterface $rule
161
     * @return $this
162
     */
163
    public function addValidation(RuleInterface $rule): self
164
    {
165
        $this->validator->addRule($rule);
166
167
        return $this;
168
    }
169
170
    /**
171
     * Add validations array
172
     * @param array<int, RuleInterface> $rules
173
     * @return self
174
     */
175
    public function addValidations(array $rules): self
176
    {
177
        $this->validator->addRules($rules);
178
179
        return $this;
180
    }
181
182
    /**
183
     * Check whether the file to upload is valid
184
     * @return bool
185
     */
186
    public function isValid(): bool
187
    {
188
        foreach ($this->files as $file) {
189
            $this->validateFile($file);
190
        }
191
192
        return empty($this->errors);
193
    }
194
195
    /**
196
     * Process upload
197
     * @return bool
198
     */
199
    public function process(): bool
200
    {
201
        if (!$this->isValid()) {
202
            return false;
203
        }
204
205
        $result = [];
206
207
        foreach ($this->files as $file) {
208
            if ($file->getError() === UPLOAD_ERR_OK) {
209
                $result[] = $this->storage->upload($file);
210
            }
211
        }
212
213
        if (count($result) === 1) {
214
            $this->uploadInfo = $result[0];
215
        } else {
216
            $this->uploadInfo = $result;
217
        }
218
219
        return true;
220
    }
221
222
    /**
223
     * Return the validation errors
224
     * @return array<int, string>
225
     */
226
    public function getErrors(): array
227
    {
228
        return $this->errors;
229
    }
230
231
    /**
232
     * Return the uploaded file information
233
     * @return UploadFileInfo|array<int, UploadFileInfo>|bool
234
     */
235
    public function getInfo()
236
    {
237
        return $this->uploadInfo;
238
    }
239
240
    /**
241
     * Validate the uploaded file
242
     * @param File $file
243
     * return void
244
     */
245
    protected function validateFile(File $file): void
246
    {
247
        foreach ($this->validator->getRules() as $rule) {
248
            /** @var RuleInterface $rule */
249
            $isValid = $rule->validate($file);
250
            if (!$isValid) {
251
                $this->errors[] = $rule->getErrorMessage($file);
252
                break;
253
            }
254
        }
255
    }
256
257
    /**
258
     * Add default rules validations
259
     * @return void
260
     */
261
    protected function addDefaultValidations(): void
262
    {
263
        $this->validator->addRules([
264
            new UploadError()
265
        ]);
266
    }
267
}
268