josiasmontag/laravel-email-verification
Laravel email verification with signed links, token-based confirmation, and configurable expiration. Adds verification routes, middleware, and notifications so new users can confirm their email address before accessing protected areas of your app.
The 1.2.3 release is a compatibility release: it declares support for Laravel 5.6 and does not signal new features, deprecations, or breaking API changes. Treat 1.2.3 as the new minimum for any 5.6 application and a drop-in replacement for 1.2.x on 5.5.
Minimal path to a working install:
composer require <vendor>/<package>:^1.2.3 — confirm the constraint resolves; if your app is on 5.6 you want >=1.2.3 so you do not get an older build that pins illuminate/support below 5.6.composer.json for extra.laravel.providers / extra.laravel.aliases. On 5.6 auto-discovery is on by default, so most packages need no config/app.php edit — but packages published before discovery support may still require a manual entry.php artisan vendor:publish --provider="Vendor\Package\PackageServiceProvider", then inspect config/<package>.php and any migrations.Where to look first, in order: composer.json (version constraints and discovery block), the README's "Installation" section, the package service provider's register()/boot() (this is the true map of what gets bound and published), then the config file once published.
First use case: resolve the package's main class out of the container rather than instantiating it — app(Vendor\Package\Client::class) or the facade, whichever the provider exposes. If that resolves cleanly in php artisan tinker, the wiring is correct and you can move on to real configuration.
Bind through the container, not new. Packages that support 5.6 almost always register a singleton or a bound interface in register(). Injecting the interface (__construct(Vendor\Package\Contracts\Client $client)) keeps you testable and lets you swap in fakes without touching call sites. Only reach for app() inside config files, service providers, or legacy code.
Two-tier configuration. Keep package defaults in config/<package>.php and app-specific values in .env, referenced from that file. Publish the config once and commit it — do not rely on the vendor copy, since vendor:publish --force will overwrite edits.
Wrap third-party calls behind your own service. The package is a dependency, not an architectural layer. Register a thin App\Services\... wrapper that takes the package class via constructor injection, and call the wrapper from controllers, jobs, and commands. When the next major lands, you change one class.
Queues and events. Anything the package does over the network should run in a queued job, not in the request cycle. If the package fires events, listen rather than subclass — event listeners survive minor upgrades far better than overridden methods.
Testing. Use the container's instance()/swap() in setUp() to bind a fake, or the package's own fake if it ships one. For HTTP-facing packages, Http::fake() (or the Guzzle mock handler on 5.6) plus withoutExceptionHandling() in tests will surface real failure modes instead of generic 500s.
Migrations and publishing in CI. If the package ships migrations, run vendor:publish --tag=<package>-migrations as part of deploy before php artisan migrate, and keep those published files in version control so schema changes are reviewable.
extra.laravel block in the vendor composer.json. Discovery is cached in bootstrap/cache/packages.php; php artisan package:discover or a composer dump-autoload fixes stale entries.php artisan config:clear in local and config:cache in production. A cached config from before the publish is a classic "my setting is ignored" bug.str_* / array_* helpers. If the package or your integration code calls them, you now need composer require laravel/helpers. This bites during upgrades more often than the package itself does.^1.2.3 in composer.json so a fresh clone or CI build gets a 5.6-compatible version, and commit composer.lock so it is reproducible.artisan route:list-style introspection; if bindings look missing, check provides() in the provider before assuming the install failed.php artisan tinker then app()->bound(Vendor\Package\Client::class) and get_class(app(Vendor\Package\Client::class)) tells you in two lines whether the container is returning the package class or a stale binding from your own provider.extend() on the container, package-published config, and events. Avoid overriding vendor classes via classmap hacks or editing vendor/ — both are invisible to code review and vanish on composer update.How can I help you explore Laravel packages today?