Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 24
0.00% covered (danger)
0.00%
0 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 2
UploadedFile
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 5
42
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 create
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
 invalid
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isEnabled
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 move
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
LocalInvalidUploadedFile
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 3
12
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
 isEnabled
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 move
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3declare(strict_types=1);
4
5namespace PeServer\Core\Mvc;
6
7use PeServer\Core\IO\Directory;
8use PeServer\Core\Throws\InvalidOperationException;
9use PeServer\Core\Throws\NotSupportedException;
10
11/**
12 * アップロードファイル。
13 *
14 * @see https://www.php.net/manual/features.file-upload.post-method.php
15 */
16class UploadedFile
17{
18    /**
19     * 生成。
20     *
21     * @param string $originalFileName [信頼できない情報] アップロード要求ファイル名。
22     * @param string $uploadedFilePath アップロードされたファイルパス。パス自体はPHP管理下の一時ファイルパスとなる。
23     * @param string $mime [信頼できない情報] アップロードされたファイルのMIME。
24     * @param int $fileSize アップロードファイルサイズ。
25     * @phpstan-param non-negative-int $fileSize
26     * @param int $errorCode エラーコード。
27     */
28    public function __construct(
29        public string $originalFileName,
30        public string $uploadedFilePath,
31        public string $mime,
32        public int $fileSize,
33        public int $errorCode,
34    ) {
35    }
36
37    #region function
38
39    /**
40     * `$_FILE[name]` から `UploadFile` を生成。
41     *
42     * @param array<string,string|int> $file
43     * @return self
44     */
45    public static function create(array $file): self
46    {
47        /** @phpstan-var non-negative-int */
48        $size = (int)$file['size'];
49
50        return new self(
51            (string)$file['name'],
52            (string)$file['tmp_name'],
53            (string)$file['type'],
54            $size,
55            (int)$file['error']
56        );
57    }
58
59    public static function invalid(string $key): self
60    {
61        return new LocalInvalidUploadedFile($key);
62    }
63
64    /**
65     * アップロードされたファイルか。
66     *
67     * 非アップロード判定にも使用可能。
68     *
69     * @return bool
70     * @see https://www.php.net/manual/function.is-uploaded-file.php
71     */
72    public function isEnabled(): bool
73    {
74        return is_uploaded_file($this->uploadedFilePath);
75    }
76
77    /**
78     * アップロードされたファイルを移動。
79     *
80     * @param string $path
81     * @see https://www.php.net/manual/function.move-uploaded-file.php
82     */
83    public function move(string $path): void
84    {
85        Directory::createParentDirectoryIfNotExists($path);
86
87        $result = move_uploaded_file($this->uploadedFilePath, $path);
88        if (!$result) {
89            throw new InvalidOperationException($path);
90        }
91    }
92
93    #endregion
94}
95
96//phpcs:ignore PSR1.Classes.ClassDeclaration.MultipleClasses
97class LocalInvalidUploadedFile extends UploadedFile
98{
99    public function __construct(
100        public readonly string $key
101    ) {
102        parent::__construct(
103            '',
104            '',
105            '',
106            0,
107            -1
108        );
109    }
110
111    public function isEnabled(): bool
112    {
113        return false;
114    }
115
116    public function move(string $path): void
117    {
118        throw new NotSupportedException();
119    }
120}