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

Image Bundle Laravel Package

arkounay/image-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require arkounay/image-bundle
    

    (Note: Despite being archived, this package works with Symfony 3.x and Doctrine ORM.)

  2. Register Bundle: Add to config/bundles.php (Symfony 4+) or AppKernel.php (Symfony 3):

    Arkounay\ImageBundle\ArkounayImageBundle::class => ['all' => true],
    
  3. Assets & Routing:

    php bin/console assets:install
    

    Add to config/routes.yaml:

    arkounay_image:
        resource: "@ArkounayImageBundle/Resources/config/routing.yml"
    
  4. Doctrine Types: In config/packages/doctrine.yaml:

    doctrine:
        dbal:
            types:
                json_image: Arkounay\ImageBundle\Type\JsonImageType
                json_images: Arkounay\ImageBundle\Type\JsonImagesType
    

First Use Case

Entity Setup:

use Arkounay\ImageBundle\Entity\Image;
use Doctrine\Common\Collections\ArrayCollection;

class Product
{
    /**
     * @ORM\Column(type="json_image")
     */
    private $thumbnail;

    /**
     * @ORM\Column(type="json_images")
     */
    private $gallery;

    public function __construct()
    {
        $this->gallery = new ArrayCollection();
    }
}

Form Integration:

use Arkounay\ImageBundle\Form\JsonImageType;
use Arkounay\ImageBundle\Form\JsonImagesType;

$builder
    ->add('thumbnail', JsonImageType::class, [
        'allow_alt' => true,
        'path_readonly' => false,
    ])
    ->add('gallery', JsonImagesType::class, [
        'min' => 1,
        'max' => 5,
    ]);

Twig Template:

<link rel="stylesheet" href="{{ asset('bundles/arkounayimage/arkounay_image_bundle.css') }}">
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
{% include '@ArkounayImage/assets/include_js.html.twig' %}

Implementation Patterns

Workflow: Image Upload in a CRUD

  1. Form Submission: The bundle handles file uploads via AJAX (jQuery-dependent). The JsonImageType/JsonImagesType automatically:

    • Validates file types/sizes (default: max_size in config).
    • Stores metadata (path, alt text, etc.) in a JSON column.
  2. Entity Hydration:

    // After form submission, Doctrine persists:
    // {
    //     "path": "/uploads/product_123.jpg",
    //     "alt": "Product Thumbnail",
    //     "mime": "image/jpeg"
    // }
    
  3. Displaying Images:

    {% for image in product.gallery %}
        <img src="{{ asset(image.path) }}" alt="{{ image.alt }}">
    {% endfor %}
    

Integration Tips

  • EasyAdminBundle:
    # config/easy_admin.yaml
    properties:
        imageCollection:
            type: Arkounay\ImageBundle\Form\JsonImagesType
            type_options:
                allow_add: true
    
  • Custom Validation: Extend the Image entity to add constraints:
    use Symfony\Component\Validator\Constraints as Assert;
    
    class Product
    {
        /**
         * @Assert\File(maxSize="2048k")
         */
        private $thumbnail;
    }
    
  • Storage Paths: Override the default upload directory in config/packages/arkounay_image.yaml:
    arkounay_image:
        upload_dir: '%kernel.project_dir%/public/uploads/custom_path'
    

Collection Handling

Leverage ninsuo/symfony-collection options for dynamic collections:

$builder->add('gallery', JsonImagesType::class, [
    'init_with_n_elements' => 3, // Pre-populate with 3 empty fields
    'add_at_the_end' => false,   // Add new items at the top
]);

Gotchas and Tips

Pitfalls

  1. Deprecated Dependencies:

    • Requires Symfony 3.x (not compatible with Symfony 4+ without adjustments).
    • jQuery 3.1.1 is hardcoded in the JS include. Update the CDN link if using a newer version:
      <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
      
  2. JSON Column Quirks:

    • Doctrine’s json type (used internally) may not support all database backends (e.g., SQLite). Test with PostgreSQL/MySQL.
    • Backup strategy: JSON columns are not easily queryable. Avoid complex WHERE clauses on json_image fields.
  3. File Permissions: Ensure the upload directory (%kernel.project_dir%/public/uploads) is writable:

    chmod -R 775 public/uploads
    
  4. EasyAdminBundle Conflicts: If using EasyAdmin, ensure the bundle’s JS doesn’t conflict with EasyAdmin’s collection widgets. Disable EasyAdmin’s collection JS for these fields:

    {% block easyadmin_collection_widget %}
        {% if form.vars.type.class is not same as('Arkounay\ImageBundle\Form\JsonImagesType') %}
            {{ parent() }}
        {% endif %}
    {% endblock %}
    

Debugging

  1. AJAX Failures: Check the browser’s Network tab for 403/500 errors. Common causes:

    • Missing ROLE_ADMIN (default). Override in config/packages/arkounay_image.yaml:
      arkounay_image:
          roles: ['ROLE_USER'] # Example: Allow all users
      
    • Incorrect CSRF token. Ensure the form includes:
      {{ form_row(form._token) }}
      
  2. Doctrine Errors: If json_image fails to persist, verify:

    • The Image entity is properly mapped (e.g., use Arkounay\ImageBundle\Entity\Image).
    • The column type is correctly set to json_image (not json).
  3. Stale Assets: Clear cache after updates:

    php bin/console cache:clear
    php bin/console assets:clear
    

Extension Points

  1. Custom Image Entity: Extend the Image entity to add fields (e.g., width, height):

    namespace App\Entity;
    
    use Arkounay\ImageBundle\Entity\Image as BaseImage;
    
    class ExtendedImage extends BaseImage
    {
        /**
         * @ORM\Column(type="integer")
         */
        private $width;
    }
    

    Update the Doctrine type to handle the extended class.

  2. Override Templates: Copy Resources/views/forms/fields.html.twig to your theme to customize the upload widget. Example: Add a preview thumbnail:

    {% block arkounay_image_widget %}
        <div class="image-preview">
            {% if form.vars.data.path %}
                <img src="{{ asset(form.vars.data.path) }}" width="100">
            {% endif %}
        </div>
        {{ parent() }}
    {% endblock %}
    
  3. Post-Upload Processing: Hook into the upload process by extending the ImageUploader service:

    # config/services.yaml
    Arkounay\ImageBundle\Service\ImageUploader:
        class: App\Service\CustomImageUploader
        decorates: arkounay_image.image_uploader
        arguments: ['@arkounay_image.image_uploader']
    
    namespace App\Service;
    
    use Arkounay\ImageBundle\Service\ImageUploader as BaseUploader;
    
    class CustomImageUploader extends BaseUploader
    {
        public function upload($file, $path)
        {
            // Add logic (e.g., resize images) before parent upload
            $this->resizeImage($file);
            return parent::upload($file, $path);
        }
    }
    
  4. Configuration Overrides: Override default settings (e.g., allowed MIME types) in config/packages/arkounay_image.yaml:

    arkounay_image:
        allowed_mime_types: ['image/jpeg', 'image/png', 'image/gif']
        max_size: 5120 # 5MB
    
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.
anousss007/vigilance
supportpal/eloquent-model
ardenexal/fhir-models
laravel-at/laravel-image-sanitize
romalytar/yammi-audit-log-laravel
ardenexal/fhir-validation
arshaviras/weather-widget
laravel-chronicle/core
sunchayn/nimbus
daikazu/eloquent-salesforce-objects
unseen-codes/chat
romalytar/yammi-jobs-monitoring-laravel
kisame76/filament-db-table-state
nqxcode/laravel-lucene-search
dpfx/laravel-livewire-wizards
workos/workos-php-laravel
sofa/laravel-global-scope
nawasara/auth-primitives
adhocrat-io/arkhe-main
make-dev/orca-harpoon