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

Attachment Manager Bundle Laravel Package

coka/attachment-manager-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the bundle via Composer:

    composer require coka/attachment-manager-bundle
    

    Enable it in config/bundles.php:

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

    php bin/console oka:attachment-manager:install
    

    Update config/packages/oka_attachment_manager.yaml to match your storage (e.g., local, s3, gcs).

  3. First Use Case Upload an attachment via a form:

    {{ form_start(form) }}
        {{ form_widget(form.file) }} <!-- 'file' must be the field name -->
    {{ form_end(form) }}
    

    Handle the upload in your controller:

    use CedrickOka\AttachmentManagerBundle\Service\AttachmentManager;
    
    public function upload(Request $request, AttachmentManager $manager)
    {
        $file = $request->file('file');
        $attachment = $manager->upload($file, 'user_attachments'); // 'user_attachments' = storage directory
        return new JsonResponse(['url' => $attachment->getUrl()]);
    }
    

Implementation Patterns

Core Workflows

  1. Uploading Files

    • Use AttachmentManager service to handle uploads:
      $attachment = $manager->upload($file, 'directory', [
          'mime_type' => 'image/jpeg',
          'custom_metadata' => ['user_id' => 123],
      ]);
      
    • Supports chunked uploads for large files (configure in oka_attachment_manager.yaml).
  2. Retrieving Attachments

    • Fetch by ID:
      $attachment = $manager->find('user_attachments', $attachmentId);
      
    • List attachments in a directory:
      $attachments = $manager->list('user_attachments');
      
  3. Deleting Files

    • Delete a single attachment:
      $manager->delete('user_attachments', $attachmentId);
      
    • Bulk delete:
      $manager->deleteMultiple('user_attachments', [$id1, $id2]);
      
  4. Integration with Entities

    • Store attachment IDs in your Doctrine entities:
      /**
       * @ORM\Column(type="string", nullable=true)
       */
      private $attachmentId;
      
    • Use a lifecycle callback to auto-cleanup:
      use Doctrine\ORM\Event\LifecycleEventArgs;
      
      public function preRemove(LifecycleEventArgs $args)
      {
          $attachmentId = $this->attachmentId;
          if ($attachmentId) {
              $manager->delete('user_attachments', $attachmentId);
          }
      }
      
  5. Symfony Forms

    • Use OkaAttachmentType for file uploads:
      use CedrickOka\AttachmentManagerBundle\Form\Type\OkaAttachmentType;
      
      $builder->add('avatar', OkaAttachmentType::class, [
          'directory' => 'user_avatars',
          'allowed_mime_types' => ['image/jpeg', 'image/png'],
      ]);
      
  6. API Responses

    • Serialize attachments for JSON APIs:
      $serializer = $this->container->get('serializer');
      $attachmentData = $serializer->serialize(
          $attachment,
          'json',
          ['groups' => ['attachment:read']]
      );
      

Advanced Patterns

  1. Custom Storage Adapters Extend CedrickOka\AttachmentManagerBundle\Storage\StorageInterface for cloud providers (e.g., Backblaze B2):

    class BackblazeStorage implements StorageInterface
    {
        public function save($file, $directory, array $options): Attachment
        {
            // Custom logic
        }
    }
    

    Register in services.yaml:

    services:
        CedrickOka\AttachmentManagerBundle\Storage\StorageInterface:
            class: App\Storage\BackblazeStorage
    
  2. Event Listeners Trigger actions on upload/delete:

    use CedrickOka\AttachmentManagerBundle\Event\AttachmentEvent;
    
    $dispatcher->addListener(
        'oka_attachment_manager.upload',
        function (AttachmentEvent $event) {
            // Log, notify, or process metadata
        }
    );
    
  3. Validation Rules Enforce file size/mime types via constraints:

    use CedrickOka\AttachmentManagerBundle\Validator\Constraints as OkaAssert;
    
    /**
     * @OkaAssert\File(
     *     maxSize="10M",
     *     mimeTypes={"image/jpeg", "image/png"}
     * )
     */
    private $file;
    
  4. Symfony Messenger Integration Queue uploads for async processing:

    use CedrickOka\AttachmentManagerBundle\Message\UploadAttachment;
    
    $bus->dispatch(new UploadAttachment(
        $file,
        'user_attachments',
        ['user_id' => 123]
    ));
    

Gotchas and Tips

Pitfalls

  1. Directory Permissions

    • Ensure var/storage/ (or custom path) is writable:
      chmod -R 775 var/storage/
      
    • For S3/GCS, verify IAM roles/credentials in oka_attachment_manager.yaml.
  2. File Overwrites

    • By default, duplicate filenames append a hash (e.g., file_123abc.jpg).
    • Disable via config:
      oka_attachment_manager:
          unique_filenames: false
      
  3. Memory Limits

    • Large files may hit PHP’s upload_max_filesize or memory_limit.
    • Use chunked uploads (enable in config):
      oka_attachment_manager:
          chunked_uploads:
              enabled: true
              chunk_size: 5M
      
  4. Doctrine Proxy Issues

    • Avoid lazy-loading attachments in entity constructors:
      // ❌ Bad: Triggers proxy loading
      public function __construct()
      {
          $this->attachment = $manager->find(...); // Avoid!
      }
      
  5. CORS for Direct Access

    • If serving files via Nginx/Apache, configure CORS headers for direct URLs:
      location /storage/ {
          add_header 'Access-Control-Allow-Origin' '*';
          alias /path/to/storage/;
      }
      

Debugging Tips

  1. Log Uploads Enable debug mode in oka_attachment_manager.yaml:

    oka_attachment_manager:
        debug: true
    

    Check logs for errors in var/log/dev.log.

  2. Validate Storage Test storage connectivity:

    php bin/console debug:container CedrickOka\AttachmentManagerBundle\Storage\StorageInterface
    

    Manually trigger a save:

    $manager->save($file, 'test_dir');
    
  3. Common Errors

    • "File not found": Verify the directory path in AttachmentManager::find().
    • Permission denied: Check umask in oka_attachment_manager.yaml:
      oka_attachment_manager:
          umask: 0002
      
    • Duplicate filenames: Reset unique_filenames or clean up manually.

Extension Points

  1. Custom Metadata Extend the Attachment entity:

    namespace App\Entity;
    
    use CedrickOka\AttachmentManagerBundle\Entity\Attachment as BaseAttachment;
    
    class Attachment extends BaseAttachment
    {
        /**
         * @ORM\Column(type="string", nullable=true)
         */
        private $customField;
    }
    

    Update the bundle’s resources/config/doctrine/Attachment.orm.xml to include your fields.

  2. Webhooks Listen for oka_attachment_manager.upload/delete events to trigger external services (e.g., Slack notifications):

    $dispatcher->addListener('oka_attachment_manager.upload', function (AttachmentEvent $event) {
        $client->post('https://hooks.slack.com/...', [
            'text' => sprintf('New attachment: %s', $event->getAttachment()->getFilename())
        ]);
    });
    
  3. Flysystem Integration Replace the default storage with Flysystem adapters:

    services:
        CedrickOka\AttachmentManagerBundle\Storage\StorageInterface:
            alias: 'oneup_flysystem.attachment_storage'
    

    Configure in oneup_flysystem.yaml:

    adapters:
        attachment_storage:
            local:
                directory: %kernel.project_dir%/var/storage
    
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.
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony
spatie/flare-daemon-runtime