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

Darvin Image Bundle Laravel Package

darvinstudio/darvin-image-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require darvinstudio/darvin-image-bundle
    

    Enable the bundle in config/bundles.php:

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

    php bin/console darvin:image:install
    

    Update config/packages/darvin_image.yaml to define:

    • storage_path: Local filesystem or cloud storage (e.g., AWS S3).
    • allowed_formats: Whitelist of permitted image types (e.g., ['jpg', 'png', 'webp']).
    • default_quality: JPEG/PNG compression level (1–100).
  3. First Use Case Upload an image via a Symfony form:

    // src/Form/ImageUploadType.php
    use DarvinStudio\DarvinImageBundle\Form\Type\ImageType;
    
    $builder->add('image', ImageType::class, [
        'label' => 'Upload Image',
        'required' => false,
    ]);
    

    Process the upload in a controller:

    // src/Controller/ImageController.php
    use DarvinStudio\DarvinImageBundle\Entity\Image;
    
    public function upload(Request $request)
    {
        $image = new Image();
        $form = $this->createForm(ImageType::class, $image);
        $form->handleRequest($request);
    
        if ($form->isSubmitted() && $form->isValid()) {
            $image->upload(); // Auto-resizes, validates, and saves
            return new JsonResponse(['path' => $image->getPath()]);
        }
    }
    

Implementation Patterns

Core Workflows

  1. Image Upload & Processing

    • Automatic Handling: The bundle processes files on upload():
      • Validates MIME type against allowed_formats.
      • Resizes to default_dimensions (configurable per entity).
      • Generates thumbnails (if thumbnail_config is set).
      • Stores metadata (e.g., width, height, filesize).
    • Custom Processing:
      $image->setWidth(800); // Override default width
      $image->setQuality(85); // Adjust compression
      $image->upload();
      
  2. Entity Integration

    • Extend DarvinStudio\DarvinImageBundle\Entity\Image or use traits:
      // src/Entity/Product.php
      use DarvinStudio\DarvinImageBundle\Entity\ImageTrait;
      
      class Product
      {
          use ImageTrait;
          // ...
      }
      
    • Define relationships in Doctrine:
      # config/doctrine/Product.orm.yml
      DarvinStudio\DarvinImageBundle\Entity\Image:
          oneToOne:
              mapping: true
              targetEntity: App\Entity\Product
              inversedBy: image
      
  3. Dynamic Thumbnails

    • Configure thumbnail presets in darvin_image.yaml:
      thumbnail_config:
          product_grid:
              width: 300
              height: 300
              crop: true
          product_detail:
              width: 800
              height: 800
              quality: 90
      
    • Generate on-the-fly:
      $thumbnail = $image->getThumbnail('product_grid');
      
  4. Cloud Storage

    • Use DarvinStudio\DarvinImageBundle\Storage\CloudStorage:
      # config/packages/darvin_image.yaml
      storage:
          adapter: aws_s3
          config:
              bucket: my-bucket
              region: us-east-1
              credentials:
                  key: "%env(AWS_KEY)%"
                  secret: "%env(AWS_SECRET)%"
      

Integration Tips

  • Symfony Uploader: Pair with VichUploaderBundle for advanced features (e.g., onUpload, onRemove hooks).
  • APIs: Return image URLs via API Platform or FOSRest:
    use ApiPlatform\Core\Annotation\ApiResource;
    use DarvinStudio\DarvinImageBundle\Entity\Image;
    
    #[ApiResource]
    class Product
    {
        #[ApiProperty(iri: 'getImage')]
        public Image $image;
    }
    
  • Frontend: Use the generated src attribute in Twig:
    <img src="{{ image.getWebPath('product_detail') }}" alt="{{ product.name }}">
    

Gotchas and Tips

Pitfalls

  1. Configuration Overrides

    • Bundle defaults may conflict with existing Symfony config (e.g., framework/filesystem). Explicitly set storage_path to avoid issues.
    • Fix: Clear cache after config changes:
      php bin/console cache:clear
      
  2. File Permissions

    • Ensure storage_path is writable by the web server user (e.g., www-data):
      chmod -R 775 var/storage
      
  3. Thumbnail Caching

    • Thumbnails are regenerated on every request by default. For performance:
      • Enable caching in darvin_image.yaml:
        thumbnail_cache:
            enabled: true
            ttl: 86400 # 1 day
        
      • Warning: Disable caching during development to see real-time changes.
  4. Doctrine Lifecycle Events

    • If using onFlush/onFlush listeners, ensure the Image entity is persisted before upload:
      $product->setImage($image);
      $entityManager->persist($product);
      $entityManager->flush(); // Required before $image->upload()
      
  5. Large Files

    • Default PHP limits (upload_max_filesize, post_max_size) may block uploads. Adjust in php.ini or .htaccess:
      upload_max_filesize = 20M
      post_max_size = 20M
      

Debugging

  • Validation Errors: Check Image entity for errors property:
    if ($image->hasErrors()) {
        dd($image->getErrors()); // Array of validation messages
    }
    
  • Storage Issues: Enable debug mode in darvin_image.yaml:
    debug: true
    
    Logs will appear in var/log/darvin_image.log.

Extension Points

  1. Custom Storage Adapters

    • Implement DarvinStudio\DarvinImageBundle\Storage\StorageInterface for custom backends (e.g., Google Cloud Storage):
      class CustomStorage implements StorageInterface
      {
          public function save(FileInfo $file): string { /* ... */ }
          public function delete(string $path): void { /* ... */ }
      }
      
    • Register in services.yaml:
      services:
          DarvinStudio\DarvinImageBundle\Storage\StorageInterface:
              alias: App\Storage\CustomStorage
      
  2. Pre/Post Upload Hooks

    • Subscribe to events:
      // src/EventListener/ImageUploadListener.php
      use DarvinStudio\DarvinImageBundle\Event\ImageUploadEvent;
      
      class ImageUploadListener
      {
          public function onUpload(ImageUploadEvent $event)
          {
              if ($event->getImage()->getMimeType() === 'image/jpeg') {
                  $event->setQuality(90); // Modify quality dynamically
              }
          }
      }
      
    • Bind in services.yaml:
      services:
          App\EventListener\ImageUploadListener:
              tags:
                  - { name: kernel.event_listener, event: darvin.image.upload, method: onUpload }
      
  3. Dynamic Resizing

    • Override the resizer service:
      services:
          DarvinStudio\DarvinImageBundle\Service\ImageResizer:
              class: App\Service\CustomImageResizer
              arguments:
                  $defaultWidth: 1200
      
    • Implement resize() method to add filters (e.g., sharpening):
      use Imagine\Image\Box;
      use Imagine\Image\Imagine;
      
      class CustomImageResizer
      {
          public function resize(Imagine $image, Box $size): Imagine
          {
              $image->resize($size);
              $image->sharpen(10); // Add custom filter
              return $image;
          }
      }
      

Pro Tips

  • Batch Processing: Use the DarvinImageBundle\Command\ProcessImagesCommand to regenerate thumbnails for existing images:
    php bin/console darvin:image:process --entity=App\Entity\Product --property=image
    
  • Lazy Loading: For large datasets, fetch image paths via DQL and hydrate Image entities manually:
    $qb = $entityManager->createQueryBuilder()
    
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