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

Entity File Bundle Laravel Package

austral/entity-file-bundle

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
1. **Installation**
   Add the bundle via Composer:
   ```bash
   composer require austral/entity-file-bundle

Enable it in config/bundles.php:

Austral\EntityFileBundle\EntityFileBundle::class => ['all' => true],
  1. Configuration Publish the default config:

    php bin/console austral:entity-file:install
    

    Update config/packages/austral_entity_file.yaml to define:

    • upload_dir (e.g., %kernel.project_dir%/public/uploads)
    • allowed_mime_types (e.g., ['image/jpeg', 'image/webp'])
    • squoosh_cli_path (if using Squoosh for compression)
  2. First Use Case: Basic File Upload Create an entity with a File property (e.g., Product):

    use Austral\EntityBundle\Interfaces\FileInterface;
    
    class Product implements FileInterface
    {
        #[ORM\Column(type: 'string', nullable: true)]
        private ?string $fileId = null;
    
        // Getters/setters for fileId
    }
    

    Use the FileUploader service in a controller:

    use Austral\EntityFileBundle\Services\FileUploader;
    
    public function uploadFile(Request $request, FileUploader $uploader): Response
    {
        $product = new Product();
        $file = $request->files->get('file');
        $uploader->upload($product, $file, 'product_image');
    
        // Persist $product...
    }
    

Implementation Patterns

Core Workflows

  1. Uploading Files

    • Single File: Use FileUploader::upload($entity, $file, $fieldName).
    • Multiple Files: Use FileUploader::uploadMultiple($entity, $files, $fieldName).
    • Validation: Leverage Symfony’s Constraints (e.g., @Assert\File) or custom validators from the bundle.
  2. Thumbnail Generation Configure thumbnails in config/packages/austral_entity_file.yaml:

    austral_entity_file:
        thumbnails:
            product_thumb:
                size: [200, 200]
                mode: outbound
                extension: webp
    

    Generate thumbnails via:

    $uploader->generateThumbnail($entity, 'product_image', 'product_thumb');
    
  3. File Downloads Use the FileDownloader service:

    use Austral\EntityFileBundle\Services\FileDownloader;
    
    public function downloadFile(FileDownloader $downloader, string $fileId): Response
    {
        return $downloader->download($fileId);
    }
    
  4. File Deletion

    $uploader->delete($entity, 'product_image');
    

Integration Tips

  • Doctrine Lifecycle Events: Hook into prePersist/preUpdate to auto-upload files:
    use Austral\EntityFileBundle\Services\FileUploader;
    use Doctrine\ORM\Event\LifecycleEventArgs;
    
    public function prePersist(LifecycleEventArgs $args): void
    {
        $entity = $args->getObject();
        if ($entity instanceof FileInterface && $entity->getFile() && !$entity->getFileId()) {
            $uploader = $this->container->get(FileUploader::class);
            $uploader->upload($entity, $entity->getFile(), 'file');
        }
    }
    
  • Symfony Forms: Use the FileType from the bundle for seamless uploads:
    $builder->add('file', FileType::class, [
        'label' => 'Product Image',
        'mapped' => false,
        'required' => false,
    ]);
    
  • Squoosh Compression: Ensure squoosh-cli is installed globally or set squoosh_cli_path in config. Compression is auto-applied for WebP files (configure via compression key in YAML).

Gotchas and Tips

Pitfalls

  1. WebP Rotation Loss

    • Issue: Exif rotation metadata is stripped when compressing WebP files. Fixed in v3.1.0 but may persist if using older versions.
    • Workaround: Use imagine/imagine directly to preserve metadata before compression:
      use Imagine\Gd\Imagine;
      $image = (new Imagine())->open($filePath);
      $image->rotate($entity->getRotationAngle());
      $image->save($filePath);
      
  2. Multi-Object Uploads

    • Issue: Uploading files for multiple entities in a single request (e.g., bulk upload) may fail silently in older versions (<v3.1.0).
    • Fix: Explicitly loop and upload files:
      foreach ($entities as $entity) {
          $uploader->upload($entity, $request->files->get('file_' . $entity->getId()), 'file');
      }
      
  3. File Permissions

    • Issue: Uploads may fail if upload_dir lacks write permissions.
    • Fix: Set correct permissions:
      chmod -R 775 %kernel.project_dir%/public/uploads
      
  4. Squoosh CLI Dependency

    • Issue: Compression fails if squoosh-cli is missing or misconfigured.
    • Debug: Verify path in config and test Squoosh manually:
      squoosh --help
      

Debugging Tips

  • Log Uploads: Enable debug mode and check Symfony logs for errors:
    # config/packages/dev/monolog.yaml
    monolog:
        handlers:
            main:
                level: debug
    
  • Validate File Paths: Use FileUploader::getFilePath($entity, $fieldName) to debug stored paths.
  • Check Entity Interface: Ensure your entity implements Austral\EntityBundle\Interfaces\FileInterface (or the updated interface in v3.1.0+).

Extension Points

  1. Custom Thumbnail Filters Extend Austral\EntityFileBundle\Services\ThumbnailGenerator to add filters (e.g., watermarks):

    class CustomThumbnailGenerator extends ThumbnailGenerator
    {
        protected function applyFilters(Imagine\ImageInterface $image): Imagine\ImageInterface
        {
            $image = parent::applyFilters($image);
            // Add custom logic (e.g., watermark)
            return $image;
        }
    }
    

    Register the service in services.yaml:

    Austral\EntityFileBundle\Services\ThumbnailGenerator:
        alias: App\Services\CustomThumbnailGenerator
    
  2. Pre/Post Upload Hooks Subscribe to events via Symfony’s event dispatcher:

    use Austral\EntityFileBundle\Events\FileUploadEvent;
    
    $dispatcher->addListener(FileUploadEvent::UPLOAD, function (FileUploadEvent $event) {
        // Pre-upload logic (e.g., validate file content)
    });
    
  3. Custom File Storage Override the default storage adapter by implementing Austral\EntityFileBundle\Storage\FileStorageInterface and binding it in services.yaml:

    austral.entity_file.storage:
        class: App\Storage\CustomFileStorage
        arguments: ['@filesystem']
    

Configuration Quirks

  • Default Field Name: If $fieldName is omitted, the bundle defaults to file. Override this in your entity’s getFileField() method.
  • Mime Type Validation: The bundle uses Symfony’s MimeTypeGuesser by default. For stricter validation, extend the FileValidator service.
  • Entity ID Requirement: File IDs are generated using the entity’s ID. Ensure your entity has a primary key (e.g., id) before upload.

```markdown
### Laravel-Specific Adaptations
While this bundle is Symfony-focused, here’s how to adapt it for Laravel (using Symfony’s components):

1. **Installation**
   Use `composer require austral/entity-file-bundle` and manually load the bundle in `bootstrap/app.php`:
   ```php
   $app->register(\Austral\EntityFileBundle\EntityFileBundle::class);
  1. Configuration Publish config via:

    php artisan vendor:publish --tag=austral_entity_file_config
    

    Update config/austral_entity_file.php.

  2. Service Binding Bind Symfony services to Laravel’s container in AppServiceProvider:

    public function register(): void
    {
        $this->app->bind(\Austral\EntityFileBundle\Services\FileUploader::class);
    }
    
  3. Doctrine Integration Use laravel-doctrine or cycle-orm to bridge Doctrine with Laravel. Example for prePersist:

    use Doctrine\ORM\Event\LifecycleEventArgs;
    use Austral\EntityFileBundle\Services\FileUploader;
    
    public function prePersist(LifecycleEventArgs $args): void
    
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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui