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

Saas Provider Bundle Laravel Package

fluxter/saas-provider-bundle

fluxter/saas-provider-bundle is a Laravel/PHP package that bundles reusable SaaS provider integration logic, helping you connect provider services and common SaaS workflows into your application with less boilerplate and a cleaner setup.

View on GitHub
Deep Wiki
Context7

Getting Started

Before you composer require anything, understand what this is: fluxter/saas-provider-bundle is a Symfony bundle, not a Laravel package. It wires into Symfony's kernel, DI container, and bundle extension system — none of which Laravel has. So the first step for a Laravel developer is not installation, it's concept extraction.

Where to look first (in the repo):

  1. DependencyInjection/ — the *Extension and Configuration classes reveal the config tree and the services the bundle registers. This is the single most informative folder for understanding intent.
  2. Resources/config/ — service definitions (YAML/XML) show what gets instantiated and how it's wired.
  3. *Provider / tenant / subscription classes — the domain logic you actually care about.
  4. The README — check the documented config keys; the bundle's "provider" abstraction is the core idea to grasp.

Minimal steps to evaluate it for a Laravel app:

git clone https://github.com/Fluxter/symfony-saas-provider-bundle
cat composer.json        # note PHP + symfony/* version constraints
grep -r "class .*Extension" src/

There is no composer require path into a Laravel skeleton — it will pull Symfony HTTP Kernel, DependencyInjection, Config, and EventDispatcher and still won't boot. Your "first use case" is therefore: read the config tree, decide whether the tenant/provider model fits your app, and if it does, port the pattern into a Laravel service provider rather than trying to install the bundle.

First use case to target: a multi-tenant SaaS where a Provider (tenant/account) is resolved per request and gates access to plans/subscriptions. That's the shape this bundle models, and it maps cleanly onto Laravel middleware + container bindings + Eloquent global scopes.

Implementation Patterns

Treat the bundle as a reference architecture, and translate Symfony idioms to Laravel ones:

Symfony bundle concept Laravel equivalent
Bundle class Package + ServiceProvider
DependencyInjection/Configuration tree config/saas.php
Service definitions in Resources/config Container bindings in register()
Tagged services (!tagged_iterator) $this->app->tag() + tagged()
Event subscribers EventServiceProvider listeners
Request listener / kernel event HTTP middleware
Compiler passes boot() logic or a dedicated registrar

Pattern 1 — Provider/Tenant registry as a singleton

// app/Providers/SaasServiceProvider.php
public function register(): void
{
    $this->app->singleton(TenantManager::class, fn ($app) =>
        new TenantManager($app['config']->get('saas.providers', []))
    );
}

Pattern 2 — Resolve the tenant in middleware

class ResolveTenant
{
    public function __construct(private TenantManager $tenants) {}

    public function handle($request, Closure $next)
    {
        $tenant = $this->tenants->resolveFromHost($request->getHost())
            ?? abort(404);

        app()->instance(CurrentTenant::class, $tenant);
        return $next($request);
    }
}

Pattern 3 — Scope Eloquent queries automatically

protected static function booted(): void
{
    static::addGlobalScope('tenant', function ($q) {
        if ($tenant = app(CurrentTenant::class)) {
            $q->where('tenant_id', $tenant->id);
        }
    });
}

Pattern 4 — Subscription/entitlement checks via Gate

Gate::define('feature', fn (User $u, string $feature) =>
    app(CurrentTenant::class)->plan()->allows($feature)
);

If you genuinely need the bundle's logic (e.g., a calculation or provider adapter you don't want to rewrite), the pragmatic route is to stand it up inside a small Symfony service and call it over HTTP or a queue — not to graft Symfony's DI into Laravel. If it's MIT (it is), copying the isolated domain class with attribution is usually cleaner.

Config integration tip: mirror the bundle's YAML config tree exactly in config/saas.php and add a php artisan vendor:publish-style stub so future readers can diff against upstream docs.

Gotchas and Tips

  • It's effectively unmaintained. Last release was 2022-07-07, 1 star, 0 dependents. Do not build billing or entitlement logic you can't replace on top of it. Port the pattern, not the dependency.
  • Version constraints will bite. Check composer.json for symfony/* and php ranges — a 2022 bundle will likely pin PHP 7.4/8.0 and Symfony 5.x, which is incompatible with current Laravel (10/11/12) on PHP 8.2+. Composer will refuse or force downgrades.
  • No facade, no contract. There's no SaasProvider:: facade and no Illuminate\Contracts binding. Everything is Symfony-typed (ContainerInterface, EventDispatcherInterface). Expect to shim interfaces if you ever interop.
  • Container semantics differ. Symfony autowiring + tagged iterators + compiler passes have no 1:1 mapping. !tagged_iterator (e.g., a list of registered providers) becomes $this->app->tag() in register() and tagged() in consumers — easy to get wrong on first pass.
  • Debugging: Symfony's profiler and debug:container don't exist here. Use php artisan tinker, dd(app(TenantManager::class)), and Telescope/logging to trace tenant resolution. Log the resolved tenant before the global scope runs or you'll get silent empty result sets.
  • Global-scope footgun. A tenant global scope will also filter migrations and seeders if applied broadly. Guard with an explicit "no tenant context" bypass and always provide an withoutGlobalScope('tenant') escape hatch for admin tooling.
  • Config quirks. Symfony config trees support env-var processors (%env(...)%) and defaults per node; Laravel's config/*.php doesn't validate shape. Add a small validation step in boot() or a config test so malformed provider definitions fail loudly instead of producing 404s.
  • Extension points: Symfony Extension::load() and compiler passes are where upstream injects behavior. If you're porting, replicate that ordering in register() (bindings) vs boot() (side effects) — mixing them causes "class not found" during resolution.
  • License hygiene: MIT means you can vendor/port freely, but keep the copyright notice in copied files and note the upstream commit you based changes on — future-you will want the diff when upstream (inevitably) goes stale.
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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect