Laravel Version
12.51.0
PHP Version
8.4.18
Database Driver & Version
N/A
Description
File::types() is declared as a static factory method that returns new static(). When called in a fluent chain on an existing File or ImageFile instance, PHP invokes the static method, which creates a new instance, silently discarding all prior configuration (image(), max(), etc.).
This makes ->types() appear chainable but it is not. There is no warning, no runtime error, and no indication that prior constraints were dropped.
With extensions() which is an instance method returning $this, it chains correctly.
Any code using File::image()->max(...)->types(...) has no size validation and the constraint is silently dropped.
Steps To Reproduce
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rules\File;
$image = UploadedFile::fake()->image('photo.jpg', 800, 600);
// This file is ~8 KB
// max() BEFORE types() → max is silently lost
$v1 = Validator::make(
['file' => $image],
['file' => [File::image()->max(1)->types(['jpg', 'jpeg'])]]
);
var_dump($v1->fails()); // false — 8 KB file passes max:1KB!
// types() BEFORE max() → max works
$v2 = Validator::make(
['file' => $image],
['file' => [File::image()->types(['jpg', 'jpeg'])->max(1)]]
);
var_dump($v2->fails()); // true — correctly rejected
// Without types() → max works
$v3 = Validator::make(
['file' => $image],
['file' => [File::image()->max(1)]]
);
var_dump($v3->fails()); // true — correctly rejected
Laravel Version
12.51.0
PHP Version
8.4.18
Database Driver & Version
N/A
Description
File::types() is declared as a static factory method that returns
new static(). When called in a fluent chain on an existing File or ImageFile instance, PHP invokes the static method, which creates a new instance, silently discarding all prior configuration (image(), max(), etc.).This makes ->types() appear chainable but it is not. There is no warning, no runtime error, and no indication that prior constraints were dropped.
With extensions() which is an instance method returning $this, it chains correctly.
Any code using File::image()->max(...)->types(...) has no size validation and the constraint is silently dropped.
Steps To Reproduce