Installation Run:
composer require duguncom/uploadbundle:~2.0
Ensure your project uses Symfony 2.x (Laravel 5.x compatibility is not natively supported; see Implementation Patterns for workarounds).
Enable the Bundle
Add to app/AppKernel.php (Symfony) or use a Laravel service provider wrapper (see below):
new Dugun\UploadBundle\DugunUploadBundle(),
Basic Configuration
Add to app/config/config.yml (Symfony) or config/services.php (Laravel):
dugun_upload:
upload_service_name: aws # or 'local' if using temporary_path
temporary_path: /tmp/dugun_uploads
credentials:
aws:
base_url: "https://s3.amazonaws.com"
bucket: "your-bucket-name"
region: "us-east-1"
credentials:
key: "%env(AWS_KEY)%"
secret: "%env(AWS_SECRET)%"
First Use Case: Upload a File
Inject the DugunUploadBundle\Service\UploadService and use:
$uploadService = $this->get('dugun_upload.upload_service');
$result = $uploadService->upload(
$filePath, // e.g., '/tmp/temp_file.jpg'
'public', // optional: storage directory prefix
['user_id' => 1] // optional: metadata
);
Laravel Note: Use a facade or bind the service in AppServiceProvider.
Service Injection
Autowire UploadService in controllers/services:
use Dugun\UploadBundle\Service\UploadService;
class MyController extends Controller {
public function uploadAction(UploadService $uploadService) {
$result = $uploadService->upload($filePath, 'profile_pics');
return new JsonResponse($result);
}
}
Form Handling
Use Symfony’s File type in forms:
$builder->add('file', FileType::class, [
'mapped' => false,
'required' => true,
]);
Process uploads in the controller:
$file = $request->files->get('file');
$tempPath = $file->getRealPath();
$uploadService->upload($tempPath, 'uploads');
Metadata Handling Pass arrays for custom metadata (e.g., user IDs, tags):
$uploadService->upload($filePath, 'avatars', [
'user_id' => auth()->id(),
'is_verified' => true,
]);
Service Provider Wrapper
Create DugunUploadServiceProvider:
use Dugun\UploadBundle\DugunUploadBundle;
use Dugun\UploadBundle\Service\UploadService;
class DugunUploadServiceProvider extends ServiceProvider {
public function register() {
$this->app->register(new DugunUploadBundle());
$this->app->bind('dugun.upload', function ($app) {
return $app['dugun_upload.upload_service'];
});
}
}
Facade for Convenience
Add to config/app.php:
'aliases' => [
'DugunUpload' => Dugun\UploadBundle\Facades\DugunUpload::class,
],
Create DugunUpload.php facade:
namespace Dugun\UploadBundle\Facades;
use Illuminate\Support\Facades\Facade;
class DugunUpload extends Facade {
protected static function getFacadeAccessor() {
return 'dugun.upload';
}
}
Request Handling
Use Laravel’s Request object:
$file = $request->file('avatar');
$tempPath = $file->store('temp');
$result = DugunUpload::upload($tempPath, 'avatars');
| Service Name | Use Case | Example Config |
|---|---|---|
aws |
Cloud storage (S3-compatible) | upload_service_name: aws |
local |
Temporary/local filesystem | temporary_path: /path/to/uploads |
| Custom | Extend for GCS, DigitalOcean, etc. | See Gotchas |
Laravel Compatibility
Kernel or use a bridge like symfony/console for CLI tools.AWS Credentials
config.yml is unsafe. Use environment variables:
credentials:
aws:
credentials:
key: "%env(AWS_ACCESS_KEY_ID)%"
secret: "%env(AWS_SECRET_ACCESS_KEY)%"
.env or Symfony’s parameters.yml for secrets.File Permissions
temporary_path is writable by the web server:
chmod -R 775 /tmp/dugun_uploads
chown -R www-data:www-data /tmp/dugun_uploads # Adjust user/group
Deprecated Symfony Features
EventDispatcher). If using Symfony 3/4/5, expect deprecation warnings.config/services.yml to use modern equivalents.Upload Failures
dugun_upload:
debug: true # Adds logging to `var/log/dugun_upload.log`
Local Storage Issues
temporary_path exists and is writable:
if (!file_exists($config['temporary_path'])) {
mkdir($config['temporary_path'], 0775, true);
}
Metadata Not Persisting
user_1_avatar.jpg). For structured data, extend the service:
$uploadService->upload($filePath, 'docs', ['user_id' => 1, 'type' => 'pdf']);
Then parse metadata from the response or use a database.Custom Storage Backends
Extend Dugun\UploadBundle\Service\UploadService:
class CustomUploadService extends UploadService {
protected function getStorageAdapter($serviceName) {
if ($serviceName === 'gcs') {
return new GoogleCloudStorageAdapter();
}
return parent::getStorageAdapter($serviceName);
}
}
Override in config.yml:
dugun_upload:
upload_service_name: gcs
Pre/Post-Upload Hooks Use Symfony events (if available) or wrap the service:
$uploadService->upload($filePath, 'images')
->then(function ($result) {
// Post-upload logic (e.g., generate thumbnail)
});
Validation Add file validation before upload:
use Symfony\Component\HttpFoundation\File\UploadedFile;
$file = $request->file('avatar');
if (!$file instanceof UploadedFile || $file->getClientMimeType() !== 'image/jpeg') {
throw new \InvalidArgumentException('Invalid file type');
}
Chunked Uploads For large files, implement chunked uploads using AWS S3’s multipart upload API (extend the service).
Caching Cache AWS credentials if using temporary sessions:
$this->app['dugun_upload.aws_credentials'] = $credentials;
Async Processing Offload uploads to a queue (e.g., Laravel Queues or Symfony Messenger):
dispatch(new HandleUpload($filePath, 'videos'));
How can I help you explore Laravel packages today?