Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Uploaded File Type Bundle Laravel Package

tiloweb/uploaded-file-type-bundle

A Symfony bundle for detecting and validating the file type of uploads. Inspect MIME types and extensions to verify incoming files, reject unexpected formats, and keep upload handling safe and consistent across your application.

View on GitHub
Deep Wiki
Context7

Getting Started

Read this first: this is a Symfony bundle, not a Laravel package. tiloweb/uploaded-file-type-bundle has no service provider, no facade, no config/uploaded-file-type.php to publish. It ships a Symfony form type and is registered via config/bundles.php. If you are evaluating it for a Laravel app, stop here — the useful outcome is borrowing the pattern, not the dependency.

For a Symfony app:

  1. Check your constraints before requiring anything. v1.0.3 is the PHP 8 / Symfony 7 cut:
    composer require tiloweb/uploaded-file-type-bundle:^1.0
    
    On PHP 7.4 or Symfony 5/6 you will resolve to v1.0.2, which is still fine but is the pre-PHP-8 branch.
  2. Enable the bundle in config/bundles.php if Flex didn't do it:
    Tiloweb\UploadedFileTypeBundle\UploadedFileTypeBundle::class => ['all' => true],
    
  3. Look here first: vendor/tiloweb/uploaded-file-type-bundle/ — read README.md, then the Form/Type/ directory for the exact FQCN of the type, then Tests/ for the most authoritative usage examples. The bundle is small; reading the whole source takes ten minutes and beats guessing at the API.
  4. First use case: a PostType/UserType with an avatar or attachment field, where you want $form->handleRequest() + $form->isValid() to hand you a usable file rather than you wiring the move logic by hand in every controller.

Implementation Patterns

Form-level usage. The bundle's whole value proposition is that the field behaves like a first-class form type. Drop it into a FormType in place of the stock FileType:

$builder->add('attachment', UploadedFileType::class, [
    'required' => false,
    'constraints' => [
        new File(['maxSize' => '4M']),
        new MimeType(['mimeTypes' => ['application/pdf']]),
    ],
]);

The two-property entity pattern is what you'll actually ship, regardless of what the bundle does internally. Keep the UploadedFile on a non-persisted property (#[ORM\Column] on nothing, and 'mapped' => false if the form type doesn't handle it), and store a string path/name on the entity. Move the file after isValid(), not during binding:

if ($form->isSubmitted() && $form->isValid()) {
    $file = $form->get('attachment')->getData();
    $name = bin2hex(random_bytes(8)).'.'.$file->guessExtension();
    $file->move($this->getParameter('kernel.project_dir').'/var/uploads', $name);
    $entity->setAttachment($name);
}

Validate with Symfony's constraints, not with if statements. File, Image, MimeType, FileValidator all operate on UploadedFile and produce form errors against the field. This is the part Laravel devs under-use: $request->validate(['avatar' => 'image|max:4096']) has a direct analogue, but attaching constraints to the form field keeps the error rendering free.

Rendering. Use form_row(form.attachment) as normal. Set enctype="multipart/form-data" on the <form> — a missing enctype produces an empty $_FILES and a silently null field, which reads like a bundle bug and isn't. Add an accept attribute for UX but never rely on it.

If you need lifecycle automation (delete old file on replace, cascade on entity delete), VichUploaderBundle is the mature option and pairs fine with this type. Don't hand-roll cleanup callbacks in five entities; write one subscriber.

Testing. Build the file with new UploadedFile($path, 'x.pdf', 'application/pdf', null, true) — the true test-mode flag skips the is-uploaded check. Submit the form via KernelBrowser::submit() and assert on the moved file's existence in a var/uploads test directory.

Laravel translation of the pattern, if that's your actual stack: the equivalent day-to-day flow is $path = $request->file('avatar')->store('avatars', 'public') plus Storage::url($path) and a 'image|max:4096' rule. The bundle's advantage in Symfony is form-type integration and constraint-driven errors; Laravel gets that from the validator and Storage facade already, so there's little to port beyond the naming convention.

Gotchas and Tips

  • v1.0.3 requires PHP 8 and adds Symfony 7. This is the breaking release. If your app is on PHP 7.4 or Symfony 5.4, composer require will downgrade to v1.0.2 or fail — use composer why-not tiloweb/uploaded-file-type-bundle 1.0.3 to see the blocking constraint instead of guessing.
  • The "fix deprecation" entry is the one that matters on Symfony 7. If your CI sets SYMFONY_DEPRECATIONS_HELPER=max[direct]=0, the pre-1.0.3 versions will fail the build on SF7 even though they "work". Pin ^1.0.3 explicitly rather than ^1.0.
  • Not a Laravel package. No ServiceProvider, not in the Laravel package registry, no config/ to publish. Any attempt to composer require it into a Laravel app will install dead weight or fail on symfony/form version conflicts.
  • php.ini limits fail silently. upload_max_filesize and post_max_size being exceeded gives you a null file or a request with empty $_FILES, not an exception. If a large upload "doesn't arrive", check phpinfo() before you check the bundle.
  • move() overwrites without warning. Always generate a unique target name (random_bytes, uuid, or uniqid). Two users uploading avatar.jpg will otherwise clobber each other.
  • Target directory must exist and be writable. move() to a non-existent directory throws; var/ permissions differ between your host and the PHP-FPM user in Docker. Create the directory in a deploy step.
  • Confirm the type is registered with bin/console debug:form (it lists available types and their options) rather than assuming. debug:container --tag=form.type also works.
  • Extension points, in order of preference: a custom FormTypeExtension to add options globally → validation constraints → a Twig form theme block if you need custom markup → finally, subclassing the type. Subclassing is the least stable against minor releases.
  • The bundle is small and thinly documented. Treat the source as the documentation and check the Tests/ directory for the intended API before assuming an option name.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console