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

Temporary Email Detection Laravel Package

jprangenbergde/temporary-email-detection

Detect disposable and temporary email addresses in Laravel with jprangenbergde/temporary-email-detection. A lightweight package for validating signups and blocking throwaway inboxes from known providers, helping keep your user base and mailing lists clean.

View on GitHub
Deep Wiki
Context7

Getting Started

This release (v1.2) is small but structural: it introduces ClientInterface and ClientFactoryInterface. Those two types are the first thing to look at, because they define the seams the rest of the package is built around — everything else (HTTP transport, auth, retries, config) sits behind them.

Start here, in this order:

  1. Read the two interfaces. Method signatures tell you the entire public surface you should code against. Anything not on ClientInterface is an implementation detail you should not depend on.
  2. Find the service provider. Look for the container bindings that map ClientFactoryInterface and ClientInterface to concrete classes. That binding is where Laravel wiring happens and where you would override behaviour.
  3. Check the config file (publish it if the package ships one with php artisan vendor:publish). Credentials, base URLs, timeouts and retry counts almost always live there rather than in the interfaces.
  4. Read the factory's make()/create() method. It decides whether you get a shared client or a fresh one per call — that distinction matters later.

A sensible first use case: take one existing controller or job that talks to the external service directly, and refactor it to type-hint ClientInterface in the constructor. If the app boots and the call still works, your bindings are correct and you have a template for the rest of the codebase.

final class SyncOrders
{
    public function __construct(private ClientInterface $client) {}

    public function handle(): void
    {
        $this->client->send(/* ... */);
    }
}

Do not resolve the factory inside business logic unless you genuinely need a different client per call (multi-tenant, per-user credentials, multiple endpoints). For the common case, inject the client.

Implementation Patterns

Inject the interface, never the concrete class. This is the whole point of the release. Constructor injection of ClientInterface gives you testability and lets the package swap implementations without touching your code.

Use the factory for context-dependent clients. When credentials or base URLs vary per tenant or per integration, inject ClientFactoryInterface and call it at the point of use. Keep the factory call in a small dedicated class (a "client resolver") rather than scattering it through controllers.

Overriding the binding. If you need custom behaviour — logging, header injection, a different transport — bind your own implementation in a service provider:

$this->app->bind(ClientFactoryInterface::class, TenantAwareClientFactory::class);

Prefer decorating the package's implementation over reimplementing the interface from scratch; you keep upstream fixes.

Testing. Because both types are interfaces, tests become straightforward:

$this->mock(ClientInterface::class, function ($mock) {
    $mock->shouldReceive('send')->once()->andReturn($response);
});

For factory-driven code, mock ClientFactoryInterface to return your fake client. This is far cleaner than hitting the network or stubbing HTTP clients, and it's the main day-to-day payoff of v1.2.

Singletons vs. fresh instances. If the provider registers the client as a singleton, state (headers, auth tokens) persists across the request — convenient, but a footgun in long-running queue workers where tokens expire. If the factory produces a new instance each time, you pay construction cost per call. Check the provider and choose deliberately; consider scoped bindings for Octane and queue contexts.

Gotchas and Tips

  • Interface ≠ contract stability. The interfaces are new in 1.2. Adding methods to them in 1.3 would be a breaking change for anyone implementing them, so expect the maintainers to grow the surface via new interfaces or optional capabilities. If you implement ClientInterface yourself, you own that risk — decorate instead where possible.
  • Binding order matters. If you override the factory binding, do it in a provider that registers after the package's provider (register() order in bootstrap/providers.php / config/app.php). Overriding in register() of your own provider usually works; overriding in boot() often does not.
  • Config caching. After changing package config, run php artisan config:clear. A stale cached config is the single most common cause of "my new credentials aren't being picked up".
  • Mocking the wrong type. A frequent error is mocking the concrete client while the container is asked for ClientInterface (or vice versa). Confirm which type is actually type-hinted before writing the mock.
  • Constructor resolution failures. Target [ClientInterface] is not instantiable means the package provider isn't registered or is deferred and never triggered. Check bootstrap/providers.php and whether the package uses deferred providers.
  • Don't leak the concrete client into return types. If a factory method returns a concrete class, you'll silently couple to it. Assert the interface in your own type declarations.
  • Extension points to watch: the factory is the intended customisation hook. If you find yourself needing behaviour the client can't express, the correct place is a decorator around ClientInterface, not a fork.
  • Verify behaviour, not just signatures. The release notes describe new types but say nothing about implementation changes. Run your existing integration tests against 1.2 before assuming the upgrade is cosmetic — a refactor to introduce interfaces can quietly change construction or lifetime semantics.
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