Installation
composer require akuma/coen-uploader-bundle
(Note: This bundle is designed for Symfony 2.8+, not Laravel. For Laravel integration, see Implementation Patterns.)
Configuration
Add to config/packages/akuma_coen_file.yaml (Symfony) or manually integrate in Laravel:
akuma_coen_file:
target_dir: "%kernel.project_dir%/public/uploads" # Override default tmp_dir
max_uploads: 5 # Customize max concurrent uploads
First Use Case
CoenFileUploader service in a controller:
use Akuma\Bundle\CoenFileBundle\Service\CoenFileUploader;
class UploadController extends AbstractController
{
public function upload(CoenFileUploader $uploader)
{
$file = $this->request->files->get('file');
$path = $uploader->upload($file);
return new Response($path);
}
}
Service Provider Create a custom provider to register the uploader as a Laravel service:
// app/Providers/CoenUploaderServiceProvider.php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Akuma\Bundle\CoenFileBundle\Service\CoenFileUploader;
class CoenUploaderServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton('coen.uploader', function ($app) {
$config = $app['config']['coen_uploader'];
return new CoenFileUploader(
$config['target_dir'] ?? sys_get_temp_dir(),
$config['max_uploads'] ?? 3
);
});
}
}
Register in config/app.php under providers.
Configuration
Add to config/coen_uploader.php:
return [
'target_dir' => storage_path('app/uploads'),
'max_uploads' => 5,
];
Usage in Controllers
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
public function upload(Request $request)
{
$file = $request->file('file');
$path = app('coen.uploader')->upload($file);
return response()->json(['path' => $path]);
}
Form Handling Use Laravel’s built-in file validation:
$request->validate([
'file' => 'required|file|max:10240', // 10MB
]);
Storage Integration For cloud storage (e.g., S3), wrap the uploader:
$localPath = app('coen.uploader')->upload($file);
$cloudPath = Storage::disk('s3')->putFile('uploads', $file);
| Workflow | Implementation |
|---|---|
| Chunked Uploads | Extend CoenFileUploader to support UploadedFile::getClientOriginalExtension(). |
| File Processing | Chain with Laravel’s File facade: File::mimeType($path). |
| Queue Jobs | Dispatch a job after upload: UploadFileJob::dispatch($file, $path). |
| Symlink Management | Use Storage::link() to expose uploads via /public/uploads. |
Symfony Dependency
Kernel or Container calls in Laravel.Directory Permissions
target_dir must be writable by the web server (e.g., chmod -R 775 storage/app/uploads).storage_path() for consistency.Max Uploads Limitation
max_uploads is a concurrency limit, not a file size limit.FormRequest:
public function rules()
{
return ['file' => 'max:10240']; // 10MB
}
No Built-in Validation
File facade:
if (!File::isValidExtension($file->getClientOriginalExtension())) {
throw new \Exception('Invalid file type.');
}
No Event System
event(new FileUploaded($file, $path));
Check Upload Paths
Log the target_dir to verify permissions:
\Log::info('Upload dir:', ['path' => app('coen.uploader')->getTargetDir()]);
Test with Small Files Start with 1KB files to rule out permission issues.
Symfony vs. Laravel Quirks
UploadedFile differs from Laravel’s. Normalize with:
$symfonyFile = new \Symfony\Component\HttpFoundation\File\UploadedFile(
$laravelFile->getRealPath(),
$laravelFile->getClientOriginalName(),
$laravelFile->getClientMimeType(),
$laravelFile->getSize(),
true
);
Custom Storage Engines
Override CoenFileUploader::upload() to support S3/GCS:
public function upload($file, $customStorage = null)
{
if ($customStorage) {
return $customStorage->putFile('uploads', $file);
}
return parent::upload($file);
}
File Naming Strategy Extend to use UUIDs or hashed names:
$extension = $file->getClientOriginalExtension();
$filename = Str::uuid() . '.' . $extension;
Laravel FileSystem Integration
Bind the uploader to Laravel’s Storage facade:
Storage::extend('coen', function ($app) {
return new CoenFileAdapter($app['coen.uploader']);
});
Note: The bundle’s minimalism requires Laravel-specific adaptations for production use. Prioritize validation, logging, and storage integration.
How can I help you explore Laravel packages today?