Weave 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

Gaufrette Extras Bundle Laravel Package

kphoen/gaufrette-extras-bundle

A Symfony bundle that adds extra functionality and integrations on top of Gaufrette, the PHP filesystem abstraction library. It wires additional filesystem adapters, services, and configuration into Symfony apps, complementing KnpGaufretteBundle for flexible, framework-native file storage handling.

View on GitHub
Deep Wiki
Context7

Getting Started

Accept up front that you cannot install this package into a modern Laravel app. kphoen/gaufrette-extras-bundle is a Symfony2 bundle: it ships a Bundle class, a DI extension, and a config tree designed to wire the kphoen/gaufrette-extras library into Symfony's container. It is marked [DEPRECATED], targets PHP 5.x/Symfony 2.x, has 3 stars and 0 dependents. Composer will almost certainly refuse to resolve symfony/http-kernel ^2.x against Laravel 10/11/12. What you can do is read it as a reference and port the ~200 lines of wiring into a Laravel service provider. That is the only realistic day-to-day use.

Read in this order:

  1. kphoen/gaufrette-extras (the library, not the bundle). Its README and source are the actual substance: a ResolvableFilesystem decorator wrapping a Gaufrette FilesystemInterface, plus resolver implementations (prefix/host-based) that turn a storage key into a public URL. This is what you're porting.
  2. The bundle's DependencyInjection/ extension (YAML/XML service definitions). This shows how the decorator and resolvers were wired together — the pattern to copy, not the code to run.
  3. Both composer.json files to confirm PHP/Symfony constraints before copying anything, so you understand why it's a non-starter.

The first use case worth caring about: you store files in a backend (local disk, S3-compatible bucket, CDN origin) and need a single object that both performs filesystem operations and resolves a path to a public URL — rendering image links in an API response without hard-coding a CDN hostname in every controller and without leaking bucket internals.

Minimal Laravel-shaped port:

composer require gaufrette/gaufrette kphoen/gaufrette-extras
// app/Providers/GaufretteServiceProvider.php
public function register(): void
{
    $this->app->singleton(ResolvableFilesystem::class, function ($app) {
        $adapter = new LocalAdapter(storage_path('app/public'));
        $filesystem = new Filesystem($adapter);

        return new ResolvableFilesystem(
            $filesystem,
            new PrefixResolver(config('filesystems.public_url'))
        );
    });
}

Inject ResolvableFilesystem where needed. Before you write any of this, ask whether Storage::disk('public')->url($path) already answers the requirement — for most Laravel apps it does, and that is the correct first answer.

Implementation Patterns

Wrap, don't replace, an existing disk. The valuable shape is the decorator: ResolvableFilesystem holds a Gaufrette FilesystemInterface, forwards read/write/exists/delete, and adds resolve($path). Bind it as a singleton and type-hint the decorator, not the underlying filesystem, so call sites get both capabilities from one dependency.

public function __construct(private ResolvableFilesystem $fs) {}

public function show(string $key): array
{
    return [
        'key' => $key,
        'url' => $this->fs->resolve($key),
        'size' => $this->fs->get($key)->getSize(),
    ];
}

Port the decorator onto Flysystem instead of Gaufrette. Gaufrette is a competing abstraction to Laravel's native Illuminate\Contracts\Filesystem\Filesystem (Flysystem-backed). Running both is a net-negative — two filesystem layers, two path-semantics conventions, and Gaufrette has no Octane story. Reimplement the ~40-line decorator against FilesystemInterface:

final class ResolvableStorage implements Filesystem
{
    public function __construct(
        private Filesystem $inner,
        private UrlResolver $resolver,
    ) {}

    public function resolve(string $path): string
    {
        return $this->resolver->resolve($path);
    }

    // forward everything else to $inner
    public function exists(string $path): bool { return $this->inner->exists($path); }
    // ...
}

Register it in config/filesystems.php as a custom disk or bind it via a provider. This preserves the pattern — one object for both I/O and URL resolution — while staying inside the abstraction Laravel maintains.

Workflow for a migration/cleanup ticket: inventory the adapters in use (local, S3, FTP, GridFS, Dropbox), map each to a Flysystem adapter, add one resolver per storage tier (public bucket vs. private/CDN), and wire them in filesystems.php. Zero new dependencies in the common case. Only scope a custom adapter if a genuinely missing backend is required — and even then, write it against the vendor SDK to implement League\Flysystem\FilesystemAdapter, not against Gaufrette.

Integration tip: keep URL resolution as a config-driven concern, not a hard-coded one. Expose the base URL via config('filesystems.disks.<name>.url') and inject it into the resolver. That makes swapping a local host for a CDN origin a one-line config change — exactly what the PrefixResolver did in the original.

Testing: because the decorator forwards to an interface, you can unit-test it against a fake Filesystem and a trivially stubbed resolver without touching real storage. Do that; it's the lowest-effort guard against path/URL drift.

Gotchas and Tips

  • Deprecation is not cosmetic. The author has explicitly marked this [DEPRECATED] — no security patches, no PHP 8 compatibility work, no bug fixes. Anything you fork, you own, including EOL Symfony 2 transitive dependencies.
  • Composer will fight you. Expect constraint conflicts on symfony/* and php. --ignore-platform-reqs may let it install but won't make Symfony 2 DI internals work at runtime — and it definitely won't survive Laravel's boot or Octane's long-lived workers.
  • Supply-chain risk is real. Pulling in legacy Symfony 2 components drags EOL packages with known CVEs into an otherwise modern app, and composer audit/Dependabot will flag and block CI.
  • Don't run two abstractions against the same bucket. Gaufrette and Flysystem have different path semantics; mixed usage produces silent data-path divergence (files written one place, looked up another). Pick one.
  • The name is misleading. gaufrette-extras-bundle is just the Symfony wiring. All the logic lives in kphoen/gaufrette-extras, which is itself unmaintained. Read the library, not the bundle.
  • Extension point, if you must. The resolver interface is the seam — implement a custom resolver (signed URLs, per-tenant CDN host, cache-busting query) rather than editing the decorator. That survives the port cleanly.
  • Debugging URL problems: if resolve() returns the wrong path or a double-slashed URL, check the prefix normalization in the resolver and the storage key format (leading slash, trailing slash). This is the single most common failure mode with prefix-based resolution and it's worth a unit test.
  • Ramp-up cost is deceptively high. Reading Symfony 2 DI extension conventions to understand this bundle has no transfer value in a Laravel shop — 2–3 days to reach "can evaluate." Redirect that time to Flysystem adapter research instead.
  • The recommendation is to not adopt it as a dependency. Use it as a design reference for the decorator and resolver pattern, then implement those few classes against Flysystem. If legacy references exist, treat removal as a small cleanup ticket during the next framework upgrade.
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.
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log