• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

codeigniter4 / CodeIgniter4 / 20566093033

29 Dec 2025 06:02AM UTC coverage: 84.546% (+0.02%) from 84.522%
20566093033

Pull #9858

github

web-flow
Merge 79091a326 into e2fc5243b
Pull Request #9858: feat: complete `Superglobals` implementation

114 of 116 new or added lines in 19 files covered. (98.28%)

1 existing line in 1 file now uncovered.

21599 of 25547 relevant lines covered (84.55%)

204.13 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.18
/system/Validation/StrictRules/FileRules.php
1
<?php
2

3
declare(strict_types=1);
4

5
/**
6
 * This file is part of CodeIgniter 4 framework.
7
 *
8
 * (c) CodeIgniter Foundation <admin@codeigniter.com>
9
 *
10
 * For the full copyright and license information, please view
11
 * the LICENSE file that was distributed with this source code.
12
 */
13

14
namespace CodeIgniter\Validation\StrictRules;
15

16
use CodeIgniter\Exceptions\InvalidArgumentException;
17
use CodeIgniter\HTTP\CLIRequest;
18
use CodeIgniter\HTTP\IncomingRequest;
19
use CodeIgniter\HTTP\RequestInterface;
20
use Config\Mimes;
21

22
/**
23
 * File validation rules
24
 *
25
 * @see \CodeIgniter\Validation\StrictRules\FileRulesTest
26
 */
27
class FileRules
28
{
29
    /**
30
     * Request instance. So we can get access to the files.
31
     *
32
     * @var IncomingRequest
33
     */
34
    protected $request;
35

36
    /**
37
     * Constructor.
38
     */
39
    public function __construct(?RequestInterface $request = null)
40
    {
41
        if (! $request instanceof RequestInterface) {
1,757✔
42
            $request = service('request');
1,757✔
43
        }
44

45
        assert($request instanceof IncomingRequest || $request instanceof CLIRequest);
46

47
        $this->request = $request;
1,757✔
48
    }
49

50
    /**
51
     * Verifies that $name is the name of a valid uploaded file.
52
     */
53
    public function uploaded(?string $blank, string $name): bool
54
    {
55
        $files = $this->request->getFileMultiple($name);
8✔
56
        if ($files === null) {
8✔
57
            $files = [$this->request->getFile($name)];
4✔
58
        }
59

60
        foreach ($files as $file) {
8✔
61
            if ($file === null) {
8✔
62
                return false;
2✔
63
            }
64

65
            if (ENVIRONMENT === 'testing') {
6✔
66
                if ($file->getError() !== 0) {
6✔
67
                    return false;
2✔
68
                }
69
            } else {
70
                // Note: cannot unit test this; no way to over-ride ENVIRONMENT?
71
                // @codeCoverageIgnoreStart
72
                if (! $file->isValid()) {
×
73
                    return false;
×
74
                }
75
                // @codeCoverageIgnoreEnd
76
            }
77
        }
78

79
        return true;
4✔
80
    }
81

82
    /**
83
     * Verifies if the file's size in Kilobytes is no larger than the parameter.
84
     */
85
    public function max_size(?string $blank, string $params): bool
86
    {
87
        // Grab the file name off the top of the $params
88
        // after we split it.
89
        $paramArray = explode(',', $params);
14✔
90
        if (count($paramArray) !== 2) {
14✔
91
            throw new InvalidArgumentException('Invalid max_size parameter: "' . $params . '"');
2✔
92
        }
93
        $name = array_shift($paramArray);
12✔
94

95
        $files = $this->request->getFileMultiple($name);
12✔
96
        if ($files === null) {
12✔
97
            $files = [$this->request->getFile($name)];
12✔
98
        }
99

100
        foreach ($files as $file) {
12✔
101
            if ($file === null) {
12✔
102
                return false;
2✔
103
            }
104

105
            if ($file->getError() === UPLOAD_ERR_NO_FILE) {
10✔
106
                return true;
×
107
            }
108

109
            if ($file->getError() === UPLOAD_ERR_INI_SIZE) {
10✔
110
                return false;
2✔
111
            }
112

113
            if ($file->getSize() / 1024 > $paramArray[0]) {
8✔
114
                return false;
4✔
115
            }
116
        }
117

118
        return true;
4✔
119
    }
120

121
    /**
122
     * Uses the mime config file to determine if a file is considered an "image",
123
     * which for our purposes basically means that it's a raster image or svg.
124
     */
125
    public function is_image(?string $blank, string $params): bool
126
    {
127
        // Grab the file name off the top of the $params
128
        // after we split it.
129
        $params = explode(',', $params);
6✔
130
        $name   = array_shift($params);
6✔
131

132
        $files = $this->request->getFileMultiple($name);
6✔
133
        if ($files === null) {
6✔
134
            $files = [$this->request->getFile($name)];
6✔
135
        }
136

137
        foreach ($files as $file) {
6✔
138
            if ($file === null) {
6✔
139
                return false;
4✔
140
            }
141

142
            if ($file->getError() === UPLOAD_ERR_NO_FILE) {
2✔
143
                return true;
×
144
            }
145

146
            // We know that our mimes list always has the first mime
147
            // start with `image` even when then are multiple accepted types.
148
            $type = Mimes::guessTypeFromExtension($file->getExtension()) ?? '';
2✔
149

150
            if (mb_strpos($type, 'image') !== 0) {
2✔
UNCOV
151
                return false;
×
152
            }
153
        }
154

155
        return true;
2✔
156
    }
157

158
    /**
159
     * Checks to see if an uploaded file's mime type matches one in the parameter.
160
     */
161
    public function mime_in(?string $blank, string $params): bool
162
    {
163
        // Grab the file name off the top of the $params
164
        // after we split it.
165
        $params = explode(',', $params);
6✔
166
        $name   = array_shift($params);
6✔
167

168
        $files = $this->request->getFileMultiple($name);
6✔
169
        if ($files === null) {
6✔
170
            $files = [$this->request->getFile($name)];
6✔
171
        }
172

173
        foreach ($files as $file) {
6✔
174
            if ($file === null) {
6✔
175
                return false;
2✔
176
            }
177

178
            if ($file->getError() === UPLOAD_ERR_NO_FILE) {
4✔
179
                return true;
×
180
            }
181

182
            if (! in_array($file->getMimeType(), $params, true)) {
4✔
183
                return false;
2✔
184
            }
185
        }
186

187
        return true;
2✔
188
    }
189

190
    /**
191
     * Checks to see if an uploaded file's extension matches one in the parameter.
192
     */
193
    public function ext_in(?string $blank, string $params): bool
194
    {
195
        // Grab the file name off the top of the $params
196
        // after we split it.
197
        $params = explode(',', $params);
6✔
198
        $name   = array_shift($params);
6✔
199

200
        $files = $this->request->getFileMultiple($name);
6✔
201
        if ($files === null) {
6✔
202
            $files = [$this->request->getFile($name)];
6✔
203
        }
204

205
        foreach ($files as $file) {
6✔
206
            if ($file === null) {
6✔
207
                return false;
2✔
208
            }
209

210
            if ($file->getError() === UPLOAD_ERR_NO_FILE) {
4✔
211
                return true;
×
212
            }
213

214
            if (! in_array($file->guessExtension(), $params, true)) {
4✔
215
                return false;
2✔
216
            }
217
        }
218

219
        return true;
2✔
220
    }
221

222
    /**
223
     * Checks an uploaded file to verify that the dimensions are within
224
     * a specified allowable dimension.
225
     */
226
    public function max_dims(?string $blank, string $params): bool
227
    {
228
        // Grab the file name off the top of the $params
229
        // after we split it.
230
        $params = explode(',', $params);
6✔
231
        $name   = array_shift($params);
6✔
232

233
        $files = $this->request->getFileMultiple($name);
6✔
234
        if ($files === null) {
6✔
235
            $files = [$this->request->getFile($name)];
6✔
236
        }
237

238
        foreach ($files as $file) {
6✔
239
            if ($file === null) {
6✔
240
                return false;
2✔
241
            }
242

243
            if ($file->getError() === UPLOAD_ERR_NO_FILE) {
4✔
244
                return true;
×
245
            }
246

247
            // Get Parameter sizes
248
            $allowedWidth  = $params[0] ?? 0;
4✔
249
            $allowedHeight = $params[1] ?? 0;
4✔
250

251
            // Get uploaded image size
252
            $info = getimagesize($file->getTempName());
4✔
253

254
            if ($info === false) {
4✔
255
                // Cannot get the image size.
256
                return false;
×
257
            }
258

259
            $fileWidth  = $info[0];
4✔
260
            $fileHeight = $info[1];
4✔
261

262
            if ($fileWidth > $allowedWidth || $fileHeight > $allowedHeight) {
4✔
263
                return false;
2✔
264
            }
265
        }
266

267
        return true;
2✔
268
    }
269

270
    /**
271
     * Checks an uploaded file to verify that the dimensions are greater than
272
     * a specified dimension.
273
     */
274
    public function min_dims(?string $blank, string $params): bool
275
    {
276
        // Grab the file name off the top of the $params
277
        // after we split it.
278
        $params = explode(',', $params);
6✔
279
        $name   = array_shift($params);
6✔
280

281
        $files = $this->request->getFileMultiple($name);
6✔
282
        if ($files === null) {
6✔
283
            $files = [$this->request->getFile($name)];
6✔
284
        }
285

286
        foreach ($files as $file) {
6✔
287
            if ($file === null) {
6✔
288
                return false;
2✔
289
            }
290

291
            if ($file->getError() === UPLOAD_ERR_NO_FILE) {
4✔
292
                return true;
×
293
            }
294

295
            // Get Parameter sizes
296
            $minimumWidth  = $params[0] ?? 0;
4✔
297
            $minimumHeight = $params[1] ?? 0;
4✔
298

299
            // Get uploaded image size
300
            $info = getimagesize($file->getTempName());
4✔
301

302
            if ($info === false) {
4✔
303
                // Cannot get the image size.
304
                return false;
×
305
            }
306

307
            $fileWidth  = $info[0];
4✔
308
            $fileHeight = $info[1];
4✔
309

310
            if ($fileWidth < $minimumWidth || $fileHeight < $minimumHeight) {
4✔
311
                return false;
2✔
312
            }
313
        }
314

315
        return true;
2✔
316
    }
317
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc