Command reference
The install command
php artisan email-magic-link:install
Publishes the configuration and prints the setup steps.
| Option | Effect |
|---|---|
--force | Overwrite files that were already published |
--views | Also publish the Blade views for customizing |
The migrations are loaded automatically, so a fresh application works without publishing
anything; this command is a convenience for customizing the config or the views. The
individual publish tags stay available. Publishing the migrations turns the bundled ones
off: once a published *_create_magic_link_tokens_table.php exists the package no longer
loads its own copies, and a host that renames the file calls
EmailMagicLinkServiceProvider::ignoreMigrations() in a service provider's register().
php artisan vendor:publish --tag=email-magic-link # everything at once
php artisan vendor:publish --tag=email-magic-link-config
php artisan vendor:publish --tag=email-magic-link-migrations
php artisan vendor:publish --tag=email-magic-link-views
php artisan vendor:publish --tag=email-magic-link-lang
| Tag | Publishes to |
|---|---|
email-magic-link | every group below, in one command |
email-magic-link-config | config/email-magic-link.php |
email-magic-link-migrations | database/migrations |
email-magic-link-views | resources/views/vendor/email-magic-link |
email-magic-link-lang | lang/vendor/email-magic-link |
The purge command
php artisan email-magic-link:purge
Deletes magic-link tokens that are expired or already consumed, and reports how many rows it removed. It takes no options and is safe to run at any cadence.
When invitations are switched on it purges those too, in the same run, and reports them on a second line. That is deliberate: one command to schedule rather than two, and one to forget. An installation without invitations sees exactly the output it always saw, because the second line only appears when the feature is on.
The package can register the schedule for you. It is off by default — a package that deletes rows on a cadence nobody chose is making your decision, and an application that already wires the command itself would end up running it twice:
// config/email-magic-link.php
'prune' => [
'schedule' => true,
'frequency' => 'daily', // hourly · daily · weekly · monthly
],
The registered entry uses withoutOverlapping(), so a purge that outlives its own interval on
a large table cannot stack. If you would rather keep the schedule in your own file, leave the
switch off and write it there:
use Illuminate\Support\Facades\Schedule;
Schedule::command('email-magic-link:purge')->daily();
It delegates to TokenStore::purge(), so a custom store implements the deletion itself. Why
the rows survive consumption in the first place is explained in
Keeping the token table small.
The doctor command
php artisan email-magic-link:doctor
Compares your published config/email-magic-link.php against the one this version ships, and
names every key your file does not mention.
Publishing the config freezes the file at that version. The package still merges its own defaults underneath it, so every key keeps working — but your file never mentions them, and a setting you cannot see is a setting you cannot tune. The gap grows quietly with every upgrade: one consuming application was found running the resend guard, a security-relevant subsystem, on defaults its configuration file had never heard of.
The command reports two things:
- Keys this version ships that your file lacks, with the value currently in force. They need no action — add the ones you want to tune, ignore the rest.
- Keys in your file this version does not know. Either they were removed in an upgrade, or the key is a typo — and a typo reads exactly like a setting that stopped working, so both are worth a look.
It exits 0 either way. A drifted config is a thing to read, not a thing to fail a deploy on.