Weave Code
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

File Bundle Laravel Package

bengor/file-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require bengor-file/file-bundle
    

    Register the bundle in config/bundles.php (Symfony 4+) or AppKernel.php (Symfony <4):

    return [
        // ...
        BenGor\FileBundle\BenGorFileBundle::class => ['all' => true],
    ];
    
  2. Configuration: Publish the default config:

    php bin/console ben-gor-file:install
    

    Edit config/packages/ben_gor_file.yaml to define storage paths, allowed extensions, and file limits.

  3. First Use Case: Upload a file via a form and process it in a controller:

    use BenGor\FileBundle\Service\FileManager;
    
    public function upload(Request $request, FileManager $fileManager)
    {
        $file = $request->files->get('file');
        $savedFile = $fileManager->save($file, 'uploads');
    
        return new JsonResponse(['path' => $savedFile->getPath()]);
    }
    

Key Classes to Explore

  • FileManager: Core service for file operations (save, delete, move, etc.).
  • FileValidator: Validate files against rules (size, type, etc.).
  • StorageAdapter: Interface for custom storage backends (e.g., S3, local filesystem).

Implementation Patterns

Common Workflows

1. File Upload with Validation

use BenGor\FileBundle\Service\FileValidator;

public function uploadWithValidation(Request $request, FileValidator $validator, FileManager $fileManager)
{
    $file = $request->files->get('file');

    // Validate against rules defined in config (e.g., maxSize: 5MB, allowedExtensions: ['jpg', 'png'])
    if (!$validator->validate($file)) {
        throw new \RuntimeException('Invalid file');
    }

    $savedFile = $fileManager->save($file, 'uploads');
    return new JsonResponse(['success' => true, 'path' => $savedFile->getUrl()]);
}

2. Custom Storage Backend

Extend StorageAdapter to support cloud storage (e.g., AWS S3):

use BenGor\FileBundle\Storage\StorageAdapter;

class S3StorageAdapter implements StorageAdapter
{
    public function save(File $file, string $directory): File
    {
        // Implement S3 upload logic
        return $file;
    }

    // Implement other required methods (delete, move, etc.)
}

Register the adapter in services.yaml:

services:
    BenGor\FileBundle\Service\FileManager:
        arguments:
            $storageAdapter: '@app.s3_storage_adapter'

3. File Processing Pipeline

Chain operations using the FileManager:

$file = $fileManager->save($request->file, 'uploads')
                    ->resize(800, 600) // If using Image extension
                    ->optimize()
                    ->getFile();

4. File Deletion with Events

Listen for file deletion events to clean up related data:

// config/services.yaml
services:
    App\EventListener\FileDeleteListener:
        tags:
            - { name: kernel.event_listener, event: ben_gor_file.delete, method: onFileDelete }

Integration Tips

  • Symfony Forms: Use the FileType with custom constraints:
    use BenGor\FileBundle\Form\Type\FileType;
    
    $builder->add('file', FileType::class, [
        'constraints' => [
            new \BenGor\FileBundle\Validator\Constraints\File([
                'maxSize' => '5M',
                'allowedExtensions' => ['jpg', 'png'],
            ]),
        ],
    ]);
    
  • APIs: Return file URLs with signed URLs (e.g., for private S3 files) via a transformer:
    use BenGor\FileBundle\Service\FileUrlGenerator;
    
    $urlGenerator = new FileUrlGenerator($fileManager, $request);
    $signedUrl = $urlGenerator->generateSignedUrl($savedFile);
    
  • Testing: Use the FileManager mock in PHPUnit:
    $mockFileManager = $this->createMock(FileManager::class);
    $mockFileManager->method('save')->willReturn(new File('path/to/file.jpg'));
    

Gotchas and Tips

Pitfalls

  1. Deprecated Symfony Version:

    • The package was last updated in 2018 and targets Symfony 2.8+. Test thoroughly with Symfony 4/5, especially for:
      • Dependency injection changes (e.g., services.yaml vs. config.yml).
      • Event system differences (e.g., kernel.event_listener tags).
    • Workaround: Use a compatibility layer or fork the package if critical issues arise.
  2. Missing Laravel-Specific Features:

    • This is a Symfony bundle, not a Laravel package. Key differences:
      • No built-in Laravel service provider registration.
      • No Eloquent model integration (e.g., file metadata storage).
    • Workaround: Create a Laravel facade or wrapper class to bridge the gap:
      class FileManagerFacade extends \Illuminate\Support\Facades\Facade
      {
          protected static function getFacadeAccessor() { return 'ben_gor_file.manager'; }
      }
      
  3. Configuration Overrides:

    • The bundle expects config in ben_gor_file.yaml. If missing, it uses defaults, which may not suit Laravel’s filesystem structure.
    • Tip: Override the storage_path in config:
      ben_gor_file:
          storage:
              local:
                  path: '%kernel.project_dir%/storage/app/files'
      
  4. File Permissions:

    • The bundle assumes the PHP process has write permissions to the configured storage path. Laravel’s storage/ directory may require:
      chmod -R 775 storage/
      
    • Tip: Use Laravel’s Storage facade to generate absolute paths if needed:
      $path = storage_path('app/files/' . $file->getFilename());
      
  5. Event Dispatching:

    • Events like ben_gor_file.upload or ben_gor_file.delete may not fire as expected in Laravel due to differing event systems.
    • Workaround: Manually dispatch events in your code:
      $event = new FileUploadEvent($file);
      $this->get('event_dispatcher')->dispatch($event, 'ben_gor_file.upload');
      

Debugging Tips

  1. Log File Operations: Enable debug mode in ben_gor_file.yaml:

    ben_gor_file:
        debug: true
    

    Logs will appear in var/log/dev.log (Symfony) or Laravel’s storage/logs.

  2. Validate File Rules: If validation fails silently, check the validator’s rules in config:

    ben_gor_file:
        validation:
            max_size: 10M
            allowed_extensions: [jpg, png, pdf]
            disallowed_extensions: []
    

    Tip: Use the FileValidator directly to debug:

    $errors = $validator->validate($file);
    dd($errors); // Inspect validation errors
    
  3. Storage Adapter Issues:

    • If files disappear or fail to save, verify the StorageAdapter is properly injected and configured.
    • Debug: Temporarily log the adapter’s save method:
      public function save(File $file, string $directory): File
      {
          \Log::debug('Saving file to: ' . $directory, ['file' => $file->getFilename()]);
          // ...
      }
      

Extension Points

  1. Custom File Metadata: Extend the File class to add Laravel-specific metadata (e.g., user_id, created_at):

    class LaravelFile extends \BenGor\FileBundle\Model\File
    {
        protected $userId;
        protected $createdAt;
    
        // Add getters/setters and hydration logic
    }
    

    Register the custom class in services.yaml:

    BenGor\FileBundle\Model\File: '@app.laravel_file'
    
  2. Dynamic Storage Paths: Override the storage path dynamically (e.g., per user):

    $fileManager->setStoragePath('uploads/' . auth()->id());
    $fileManager->save($file);
    
  3. Presigned URLs: For cloud storage (e.g., S3), create a custom FileUrlGenerator:

    use Aws\S3\S3Client;
    
    class S3UrlGenerator implements FileUrlGeneratorInterface
    {
        public function generateSignedUrl(File $file): string
        {
            $s3 = new S3Client([/* config */]);
            return $s3->getObjectUrl('bucket', $file->getPath());
        }
    }
    
  4. **

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.
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours