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

2lenet/file-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation Add the package via Composer (direct Git URL due to lack of Packagist listing):

    composer require 2lenet/file-bundle
    

    Register the bundle in config/bundles.php:

    return [
        // ...
        FileBundle\FileBundle::class => ['all' => true],
    ];
    
  2. First Use Case Inject FileManager into a controller/service and generate a filename for an entity’s file:

    use FileBundle\Manager\FileManagerInterface;
    
    class MyController extends AbstractController
    {
        public function __construct(private FileManagerInterface $fileManager) {}
    
        public function uploadFile(MyEntity $entity)
        {
            $fileSpec = $this->fileManager->getLocalFilename(
                MyEntity::PDF_STORAGE_NAME,  // Constant in entity
                $entity,
                'pdf'                        // File extension
            );
            // Use $fileSpec['path'] (absolute) and $fileSpec['filename'] (DB-safe)
        }
    }
    

Implementation Patterns

Core Workflows

  1. Entity Integration

    • Define storage constants in your entity (e.g., PDF_STORAGE_NAME = 'user_pdf').
    • Ensure entities have a getId() method (required by FileManager).
  2. File Storage

    • Local Files: Use getLocalFilename() for direct filesystem storage.
      $fileSpec = $this->fileManager->getLocalFilename('store_name', $entity, 'ext');
      // $fileSpec = ['path' => '/absolute/path', 'filename' => 'hash.ext']
      
    • Database Storage: Use getDatabaseFilename() for storing paths in DB (e.g., for cloud storage):
      $dbPath = $this->fileManager->getDatabaseFilename('store_name', $entity, 'ext');
      
  3. Validation & Sanitization

    • The bundle auto-sanitizes filenames (e.g., replaces spaces with underscores).
    • Extensions are validated against a whitelist (configurable via config/packages/file_bundle.yaml).
  4. Custom Storage Engines

    • Extend FileBundle\Storage\StorageInterface to support S3, Dropbox, etc.:
      class S3Storage implements StorageInterface {
          public function getPath(string $storeName): string { ... }
          public function getFilename(string $storeName, string $id, string $extension): string { ... }
      }
      
    • Register in services.yaml:
      FileBundle\Manager\FileManager:
          arguments:
              $storage: '@app.s3_storage'  # Your custom service
      

Gotchas and Tips

Pitfalls

  1. No Packagist Listing

    • Direct Git dependency may cause versioning issues. Pin to a commit/tag:
      "2lenet/file-bundle": "dev-main#123abc"
      
  2. Storage Naming Collisions

    • Reuse store_name across entities? Files will share the same directory. Use unique prefixes (e.g., user_avatar, product_manual).
  3. Missing getId()

    • FileManager expects entities to implement getId(). Use traits or abstract classes to enforce this:
      abstract class BaseEntity {
          abstract public function getId(): ?int;
      }
      
  4. Extension Whitelist

    • Default allowed extensions: ['jpg', 'png', 'pdf', 'txt']. Override in config:
      file_bundle:
          allowed_extensions: ['jpg', 'png', 'pdf', 'docx', 'xlsx']
      

Debugging

  • Filename Generation: Log $fileSpec to verify paths/filenames:
    $this->logger->debug('Generated file spec', ['spec' => $fileSpec]);
    
  • Storage Paths: Check config/packages/file_bundle.yaml for storage_path (defaults to public/uploads).

Extension Points

  1. Custom Filename Hashing Override the hashing logic in a custom StorageInterface implementation:

    public function getFilename(string $storeName, string $id, string $extension): string {
        return md5($id . $extension) . '.' . $extension; // Custom hash
    }
    
  2. Event Listeners Hook into file operations via Symfony events (e.g., file.pre_upload):

    # config/services.yaml
    FileBundle\EventListener\FileUploadListener:
        tags:
            - { name: kernel.event_listener, event: file.pre_upload, method: onPreUpload }
    
  3. Symfony Uploader Integration Pair with VichUploaderBundle for seamless file handling:

    use Vich\UploaderBundle\Mapping\Annotation as Vich;
    
    class MyEntity {
        #[Vich\UploadableField(mapping: 'user_pdf', fileNameProperty: 'pdfPath')]
        private ?File $pdfFile = null;
    }
    
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky