Completed
Push — 2.1 ( 885479...e0a7ba )
by
unknown
11:53
created

UploadedFile::reset()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 3
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 2
1
<?php
2
/**
3
 * @link http://www.yiiframework.com/
4
 * @copyright Copyright (c) 2008 Yii Software LLC
5
 * @license http://www.yiiframework.com/license/
6
 */
7
8
namespace yii\http;
9
10
use Psr\Http\Message\StreamInterface;
11
use Psr\Http\Message\UploadedFileInterface;
12
use yii\base\BaseObject;
13
use yii\base\InvalidArgumentException;
14
use yii\di\Instance;
15
16
/**
17
 * UploadedFile represents the information for an uploaded file.
18
 *
19
 * You can retrieve the set of an uploaded file from application 'request' component:
20
 *
21
 * ```php
22
 * $uploadedFiles = Yii::$app->request->getUploadedFiles();
23
 * ```
24
 *
25
 * You can use [[saveAs()]] to save file on the server.
26
 * You may also query other information about the file, including [[clientFilename]],
27
 * [[tempFilename]], [[clientMediaType]], [[size]] and [[error]].
28
 *
29
 * For more details and usage information on UploadedFile, see the [guide article on handling uploads](guide:input-file-upload)
30
 * and [PSR-7 Uploaded Files specs](http://www.php-fig.org/psr/psr-7/#16-uploaded-files).
31
 *
32
 * @property string $clientFilename the original name of the file being uploaded.
33
 * @property int $error an error code describing the status of this file uploading.
34
 * @property int $size the actual size of the uploaded file in bytes.
35
 * @property string $clientMediaType  the MIME-type of the uploaded file (such as "image/gif").
36
 * Since this MIME type is not checked on the server-side, do not take this value for granted.
37
 * Instead, use [[\yii\helpers\FileHelper::getMimeType()]] to determine the exact MIME type.
38
 * @property string $baseName Original file base name. This property is read-only.
39
 * @property string $extension File extension. This property is read-only.
40
 * @property bool $hasError Whether there is an error with the uploaded file. Check [[error]] for detailed
41
 * error code information. This property is read-only.
42
 *
43
 * @author Qiang Xue <[email protected]>
44
 * @author Paul Klimov <[email protected]>
45
 * @since 2.0
46
 */
47
class UploadedFile extends BaseObject implements UploadedFileInterface
48
{
49
    /**
50
     * @var string the path of the uploaded file on the server.
51
     * Note, this is a temporary file which will be automatically deleted by PHP
52
     * after the current request is processed.
53
     */
54
    public $tempFilename;
55
56
    /**
57
     * @var string the original name of the file being uploaded
58
     */
59
    private $_clientFilename;
60
    /**
61
     * @var string the MIME-type of the uploaded file (such as "image/gif").
62
     * Since this MIME type is not checked on the server-side, do not take this value for granted.
63
     * Instead, use [[\yii\helpers\FileHelper::getMimeType()]] to determine the exact MIME type.
64
     */
65
    private $_clientMediaType;
66
    /**
67
     * @var int the actual size of the uploaded file in bytes
68
     */
69
    private $_size;
70
    /**
71
     * @var int an error code describing the status of this file uploading.
72
     * @see http://www.php.net/manual/en/features.file-upload.errors.php
73
     */
74
    private $_error;
75
    /**
76
     * @var StreamInterface stream for this file.
77
     * @since 2.1.0
78
     */
79
    private $_stream;
80
81
82
    /**
83
     * String output.
84
     * This is PHP magic method that returns string representation of an object.
85
     * The implementation here returns the uploaded file's name.
86
     * @return string the string representation of the object
87
     */
88
    public function __toString()
89
    {
90
        return $this->clientFilename;
91
    }
92
93
    /**
94
     * Saves the uploaded file.
95
     * Note that this method uses php's move_uploaded_file() method. If the target file `$file`
96
     * already exists, it will be overwritten.
97
     * @param string $file the file path used to save the uploaded file
98
     * @param bool $deleteTempFile whether to delete the temporary file after saving.
99
     * If true, you will not be able to save the uploaded file again in the current request.
100
     * @return bool true whether the file is saved successfully
101
     * @see error
102
     */
103
    public function saveAs($file, $deleteTempFile = true)
104
    {
105
        if ($this->error == UPLOAD_ERR_OK) {
106
            if ($deleteTempFile) {
107
                $this->moveTo($file);
108
                return true;
109
            } elseif (is_uploaded_file($this->tempFilename)) {
110
                return copy($this->tempFilename, $file);
111
            }
112
        }
113
        return false;
114
    }
115
116
    /**
117
     * @return string original file base name
118
     */
119 1
    public function getBaseName()
120
    {
121
        // https://github.com/yiisoft/yii2/issues/11012
122 1
        $pathInfo = pathinfo('_' . $this->getClientFilename(), PATHINFO_FILENAME);
123 1
        return mb_substr($pathInfo, 1, mb_strlen($pathInfo, '8bit'), '8bit');
124
    }
125
126
    /**
127
     * @return string file extension
128
     */
129 2
    public function getExtension()
130
    {
131 2
        return strtolower(pathinfo($this->getClientFilename(), PATHINFO_EXTENSION));
132
    }
133
134
    /**
135
     * @return bool whether there is an error with the uploaded file.
136
     * Check [[error]] for detailed error code information.
137
     */
138
    public function getHasError()
139
    {
140
        return $this->error != UPLOAD_ERR_OK;
141
    }
142
143
    /**
144
     * {@inheritdoc}
145
     * @since 2.1.0
146
     */
147 3
    public function getStream()
148
    {
149 3
        if (!$this->_stream instanceof StreamInterface) {
150 2
            if ($this->_stream === null) {
151 1
                if ($this->getError() !== UPLOAD_ERR_OK) {
152
                    throw new \RuntimeException('Unable to create file stream due to upload error: ' . $this->getError());
153
                }
154
                $stream = [
155 1
                    'class' => FileStream::class,
156 1
                    'filename' => $this->tempFilename,
157 1
                    'mode' => 'r',
158
                ];
159 1
            } elseif ($this->_stream instanceof \Closure) {
160 1
                $stream = call_user_func($this->_stream, $this);
161
            } else {
162 1
                $stream = $this->_stream;
163
            }
164
165 2
            $this->_stream = Instance::ensure($stream, StreamInterface::class);
166
        }
167 3
        return $this->_stream;
168
    }
169
170
    /**
171
     * @param StreamInterface|\Closure|array $stream stream instance or its DI compatible configuration.
172
     * @since 2.1.0
173
     */
174 5
    public function setStream($stream)
175
    {
176 5
        $this->_stream = $stream;
0 ignored issues
show
Documentation Bug introduced by
It seems like $stream can also be of type object<Closure> or array. However, the property $_stream is declared as type object<Psr\Http\Message\StreamInterface>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
177 5
    }
178
179
    /**
180
     * {@inheritdoc}
181
     * @since 2.1.0
182
     */
183
    public function moveTo($targetPath)
184
    {
185
        if ($this->error !== UPLOAD_ERR_OK) {
186
            throw new \RuntimeException('Unable to move file due to upload error: ' . $this->error);
187
        }
188
        if (!move_uploaded_file($this->tempFilename, $targetPath)) {
189
            throw new \RuntimeException('Unable to move uploaded file.');
190
        }
191
    }
192
193
    /**
194
     * {@inheritdoc}
195
     * @since 2.1.0
196
     */
197 1
    public function getSize()
198
    {
199 1
        return $this->_size;
200
    }
201
202
    /**
203
     * @param int $size the actual size of the uploaded file in bytes.
204
     * @throws InvalidArgumentException on invalid size given.
205
     * @since 2.1.0
206
     */
207 28
    public function setSize($size)
208
    {
209 28
        if (!is_int($size)) {
210
            throw new InvalidArgumentException('"' . get_class($this) . '::$size" must be an integer.');
211
        }
212 28
        $this->_size = $size;
213 28
    }
214
215
    /**
216
     * {@inheritdoc}
217
     * @since 2.1.0
218
     */
219 21
    public function getError()
220
    {
221 21
        return $this->_error;
222
    }
223
224
    /**
225
     * @param int $error upload error code.
226
     * @throws InvalidArgumentException on invalid error given.
227
     * @since 2.1.0
228
     */
229 29
    public function setError($error)
230
    {
231 29
        if (!is_int($error)) {
232
            throw new InvalidArgumentException('"' . get_class($this) . '::$error" must be an integer.');
233
        }
234 29
        $this->_error = $error;
235 29
    }
236
237
    /**
238
     * {@inheritdoc}
239
     * @since 2.1.0
240
     */
241 14
    public function getClientFilename()
242
    {
243 14
        return $this->_clientFilename;
244
    }
245
246
    /**
247
     * @param string $clientFilename the original name of the file being uploaded.
248
     * @since 2.1.0
249
     */
250 28
    public function setClientFilename($clientFilename)
251
    {
252 28
        $this->_clientFilename = $clientFilename;
253 28
    }
254
255
    /**
256
     * {@inheritdoc}
257
     * @since 2.1.0
258
     */
259 1
    public function getClientMediaType()
260
    {
261 1
        return $this->_clientMediaType;
262
    }
263
264
    /**
265
     * @param string $clientMediaType the MIME-type of the uploaded file (such as "image/gif").
266
     * @since 2.1.0
267
     */
268 28
    public function setClientMediaType($clientMediaType)
269
    {
270 28
        $this->_clientMediaType = $clientMediaType;
271 28
    }
272
}
273