Upgrading
On this page:
- Upgrading to v8
- Upgrading to v7
- Upgrading to v6
Upgrading to v8
V8 brings a completely redesigned Mailcoach, as such this release is light on breaking changes in functionality but can be a time consuming upgrade if you’ve customised any views.
Updating your composer.json
-
Update the requirement of
spatie/laravel-mailcoach
to^8.0
-
Run a composer update
composer update spatie/laravel-mailcoach -W
Clear your icon & view cache
php artisan icon:clear php artisan view:clear
Add a scheduled task to calculate transactional mail statistics
$schedule->command('mailcoach:calculate-transactional-statistics')->everyMinute();
View changes
Most of the views have changed considerably. If you have published the Mailcoach views and have made changes, the most straightforward way to update them is to run:
php artisan vendor:publish --tag=mailcoach-views --force
And re-apply any changes you made previously to the views.
Config changes
The default TextAreaEditorComponent
has been removed, the new defaults in the config file are the following:
'content_editor' => \Spatie\Mailcoach\Livewire\Editor\TextAreaEditorComponent::class, 'content_editor' => \Spatie\Mailcoach\Domain\Editor\Markdown\Editor::class, 'template_editor' => \Spatie\Mailcoach\Livewire\Editor\TextAreaEditorComponent::class, 'template_editor' => \Spatie\Mailcoach\Domain\Editor\Codemirror\Editor::class,
Migrations
Only 2 columns have been added in the new release, you can add them using this migration:
return new class extends Migration { public function up() { Schema::table('mailcoach_transactional_mail_log_items', function (Blueprint $table) { $table->string('mail_name')->nullable()->after('mailable_class'); $table->index(['mail_name', 'created_at'], 'mail_name_index'); }); Schema::table('mailcoach_tags', function (Blueprint $table) { $table->text('description')->nullable()->after('name'); }); } };
Sendinblue renamed to Brevo
Any references that still existed have been renamed from Sendinblue to Brevo. Make sure any references in your own codebase are updated as well.
Upgrading the standalone spatie/Mailcoach skeleton
If you’ve created a Mailcoach Self-Hosted project using our starter skeleton. Be sure to upgrade the provided components as well, check out the full diff for all the required changes: https://github.com/spatie/Mailcoach/commit/67dce12b850762c771239904b6eb14edb7380fa4
Upgrading to v7
Updating your composer.json
- If your
composer.json
contains any of the additional Mailcoach packages, you can safely remove them. They are now included in the corelaravel-mailcoach
package. - Update the requirement of
spatie/laravel-mailcoach
to^7.0
-
laravel/sanctum
is no longer a requirement for Mailcoach. If you are not using this inside your application, make sureconfig/sanctum.php
is removed.
Packages safe to remove
{ "require": { "spatie/laravel-mailcoach-editor": "^2.0", "spatie/laravel-mailcoach-mailgun-feedback": "^5.0", "spatie/laravel-mailcoach-mailgun-setup": "^1.0", "spatie/laravel-mailcoach-markdown-editor": "^2.0", "spatie/laravel-mailcoach-monaco": "^3.0", "spatie/laravel-mailcoach-postmark-feedback": "^5.0", "spatie/laravel-mailcoach-postmark-setup": "^1.0", "spatie/laravel-mailcoach-sendgrid-feedback": "^5.0", "spatie/laravel-mailcoach-sendgrid-setup": "^1.0", "spatie/laravel-mailcoach-sendinblue-feedback": "^1.0", "spatie/laravel-mailcoach-sendinblue-setup": "^1.0", "spatie/laravel-mailcoach-ses-feedback": "^5.0", "spatie/laravel-mailcoach-ses-setup": "^1.0", "spatie/laravel-mailcoach-unlayer": "^3.0", } }
Clear your view cache
php artisan view:clear
Encryption has been removed
Mailcoach no longer supports encrypting the data of subscribers. This caused too many issues with Mailcoach features.
Be sure to decrypt before upgrading to v8, you can do this with the steps below:
- Disable encryption by setting
mailcoach.encryption.enabled
tofalse
- Create & run the command below to decrypt all subscribers
<?php namespace App\Console\Commands; use Illuminate\Console\Command; use Illuminate\Support\Facades\DB; use Illuminate\Support\Str; use ParagonIE\CipherSweet\BlindIndex; use ParagonIE\CipherSweet\CipherSweet as CipherSweetEngine; use ParagonIE\CipherSweet\EncryptedRow; use Spatie\Mailcoach\Domain\Audience\Encryption\Transformation\EmailFirstPart; use Spatie\Mailcoach\Domain\Audience\Encryption\Transformation\EmailSecondPart; use Spatie\Mailcoach\Domain\Audience\Encryption\Transformation\Lowercase; use Spatie\Mailcoach\Domain\Audience\Models\Subscriber; class DecryptSubscribersCommand extends Command { protected $signature = 'app:decrypt-subscribers'; protected $description = 'Decrypts all subscribers'; public function handle(): void { $encryptionKey = config('mailcoach.encryption.key'); if (Str::startsWith($encryptionKey, $prefix = 'base64:')) { $encryptionKey = base64_decode(Str::after($encryptionKey, $prefix)); } config()->set('ciphersweet.providers.string.key', $encryptionKey); $row = new EncryptedRow( app(CipherSweetEngine::class), (new Subscriber())->getTable(), ); $row ->addTextField('email') ->addTextField('first_name') ->addTextField('last_name'); $row->addBlindIndex('email', new BlindIndex('email_first_part', [new EmailFirstPart()])); $row->addBlindIndex('email', new BlindIndex('email_second_part', [new EmailSecondPart()])); $row->addBlindIndex('first_name', new BlindIndex('first_name', [new Lowercase()])); $row->addBlindIndex('last_name', new BlindIndex('last_name', [new Lowercase()])); Subscriber::each(function (Subscriber $subscriber) use ($row) { $subscriber->setRawAttributes( $row ->setPermitEmpty(config('ciphersweet.permit_empty', false)) ->decryptRow($subscriber->getAttributes()), true ); DB::table($subscriber->getTable()) ->where('id', $subscriber->id) ->update([ 'first_name' => $subscriber->first_name, 'last_name' => $subscriber->last_name, 'email' => $subscriber->email, ]); }); } }
- Change the
email
,first_name
andlast_name
columns to strings
Schema::table('mailcoach_subscribers', function (Blueprint $table): void { $table->string('email')->change(); $table->string('first_name')->nullable()->change(); $table->string('last_name')->nullable()->change(); });
- Drop the
blind_indexes
table
Removed User
model
Mailcoach no longer provides a User
model of its own. You can now extend the default Laravel model instead and implement our MailcoachUser
interface:
- use \Spatie\Mailcoach\Domain\Settings\Models\User as MailcoachUserModel; + use Illuminate\Foundation\Auth\User as Authenticatable; + use Spatie\Mailcoach\Domain\Settings\Models\MailcoachUser; - class User extends MailcoachUserModel + class User extends Authenticatable implements MailcoachUser + public function canViewMailcoach(): bool + { + return true; + }
Inside the canViewMailcoach()
method you can add additional checks if needed for your use-case.
// config/auth.php 'providers' => [ 'users' => [ 'driver' => 'eloquent', - 'model' => \Spatie\Mailcoach\Domain\Settings\Models\User::class, + 'model' => \App\User::class, ], ]
Config changes
There have been numerous config changes, you can view the full diff here: https://github.com/spatie/laravel-mailcoach/pull/1360/files
The easiest way to update this is to run
php artisan vendor:publish --tag=mailcoach-config --force
And re-apply any changes you made previously to the config.
Laravel Sanctum is no longer included
In an effort to be more flexible and letting the package users choose which authentication systems to use. Mailcoach no longer configures Laravel Sanctum by default.
If you’d like to continue using sanctum, you can install and configure it according to the docs.
View changes
Some views have changed considerably, take a look at the PR diff here: https://github.com/spatie/laravel-mailcoach/pull/1360/files
The easiest way to update this is to run
php artisan vendor:publish --tag=mailcoach-views --force
And re-apply any changes you made previously to the views.
Livewire namespace has moved
If you have extended any Mailcoach Livewire components, their namespace has been moved from
Spatie\Mailcoach\Http\Livewire
to
Spatie\Mailcoach\Livewire
Migrations
Like with previous upgrades, we’ve supplied a migration that will update all the necessary columns and move over any existing data.
Unlike previous upgrades, we suggest doing this upgrade in 3 steps:
warning
Make sure to take a backup before running any migrations or commands.
1. Adding new columns
You’ll find the Add Columns Migration
here.
Copy and paste this migration into your project to run it.
You might need to tweak this migration to fit your needs.
2. Migrating data
We made a console command to upgrade your data to the new structure.
If you installed mailcoach as a package in an existing application, you might need to tweak this command to fit your needs.
You’ll find the Add Columns Command
here.
Copy and paste this command into your project to run it.
You might need to tweak this migration to fit your needs.
We suggest running this in steps in either a migration or console command depending on what you’re comfortable with.
3. Remove old columns and data
warning
Be sure to verify that the data migration ran successfully and Mailcoach v8 is working correctly before running this migration.
You’ll find the Cleanup Migration
here.
Copy and paste this migration into your project to run it.
You might need to tweak this migration to fit your needs.
Upgrading to v6
This version adds numerous new features and a completely new look to Mailcoach.
Some notable features:
- Completely new design with improved UX
- Add & manage multiple mailers with different providers with automatic setup
- Show a website archive of your email list’s campaigns
- A full-featured template system
- A new & improved Markdown editor
- Send outgoing webhooks
- Improved list insights & charts
- A new “Manage preferences” screen where subscribers can manage the (public) tags attached to them
- A command palette
- Automations can be configured to run more than once for a subscriber
- The ability to override, replace and extend every page of Mailcoach
Updating your composer.json
- If your
composer.json
containsspatie/mailcoach-ui
, you can remove this as it’s now included within the corelaravel-mailcoach
package. - Update the requirement of
spatie/laravel-mailcoach
to^6.0
- Mailcoach now requires PHP 8.1, so make sure to update that requirement as well
"require": { - "php": "^8.0", + "php": "^8.1", "fruitcake/laravel-cors": "^2.0.5", "guzzlehttp/guzzle": "^7.2", "laravel/framework": "^9.0", "laravel/horizon": "^5.9", "laravel/tinker": "^2.7", - "spatie/laravel-mailcoach": "^5.0", + "spatie/laravel-mailcoach": "^6.0", - "spatie/mailcoach-ui": "^5.0" },
Composer scripts
- The composer hook command has been renamed, make sure to edit this in your
scripts
section if it is present, usually only in a standalone installation: - The necessary migrations will now be published by the publish command
"scripts": { "post-autoload-dump": [ "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump", "@php artisan package:discover --ansi" ], "post-root-package-install": [ "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" ], "post-create-project-cmd": [ "@php artisan key:generate --ansi", - "@php artisan vendor:publish --tag mailcoach-migrations", - "@php artisan vendor:publish --tag mailcoach-ui-migrations", "@php artisan mailcoach:prepare-git-ignore", - "@php artisan mailcoach:execute-composer-hook" + "@php artisan mailcoach:publish" ], "post-update-cmd": [ - "@php artisan mailcoach:execute-composer-hook", + "@php artisan mailcoach:publish", "@php artisan vendor:publish --tag=laravel-assets --ansi --force" ] }
Remove the mailcoach-ui routes
Mailcoach UI required separate routes to be registered, in the standalone version these are registered inside your RouteServiceProvider
, you can remove these and replace them by the default Mailcoach route macro:
public function boot() { ... - Route::mailcoachUi('/'); + Route::mailcoach('/'); ... }
After this, you can run a composer update
Update your Schedule
There have been a few changes to the scheduled commands, make sure your Mailcoach commands in your app/Console/Kernel.php
file look like this:
protected function schedule(Schedule $schedule) { $schedule->command('mailcoach:send-automation-mails')->everyMinute(); $schedule->command('mailcoach:send-scheduled-campaigns')->everyMinute(); $schedule->command('mailcoach:send-campaign-mails')->everyMinute(); $schedule->command('mailcoach:run-automation-triggers')->everyMinute(); $schedule->command('mailcoach:run-automation-actions')->everyMinute(); $schedule->command('mailcoach:calculate-statistics')->everyMinute(); $schedule->command('mailcoach:calculate-automation-mail-statistics')->everyMinute(); $schedule->command('mailcoach:send-campaign-summary-mail')->hourly(); $schedule->command('mailcoach:cleanup-processed-feedback')->hourly(); $schedule->command('mailcoach:send-email-list-summary-mail')->mondays()->at('9:00'); $schedule->command('mailcoach:delete-old-unconfirmed-subscribers')->daily(); }
Methods like runInBackground()
and withoutOverlapping()
are no longer necessary as we dispatch unique jobs inside the command instead.
Update the login route
Mailcoach has now prefixed its authentication routes, if you don’t have any login route of your own, add the following to your app/Exceptions/Handler.php
:
protected function unauthenticated($request, AuthenticationException $exception) { return $this->shouldReturnJson($request, $exception) ? response()->json(['message' => $exception->getMessage()], 401) : redirect()->guest($exception->redirectTo() ?? route('mailcoach.login')); }
Configuration updates
- Delete the
config/mailcoach-ui.php
file if present in your installation, be sure to port over any changes to theconfig/mailcoach.php
config file.
A full diff of the config file can be found here
We recommend running php artisan vendor:publish --tag=mailcoach-config --force
which will override your old configuration file with the new one. Using a git diff you can then re-apply any changes you previously made to your configuration file.
Notable changes to the config file are documented below:
Throttling
Throttling config is no longer set inside the Mailcoach configuration file, these settings can be controlled for each mailer
Welcome mails
Any configuration relating to welcome mails have been removed, you can now create a welcome automation instead.
Livewire
All views now use Livewire components which you can override in the config to add your own functionality if necessary.
Horizon
A schedule queue was added to Mailcoach, make sure your horizon config contains it:
'mailcoach-general' => [ 'connection' => 'mailcoach-redis', - 'queue' => ['general', 'mailcoach', 'mailcoach-feedback', 'send-mail', 'send-automation-mail'], + 'queue' => ['general', 'mailcoach-schedule', 'mailcoach', 'mailcoach-feedback', 'send-mail', 'send-automation-mail'], 'balance' => 'auto', 'processes' => 10, 'tries' => 2, 'timeout' => 60 * 60, ],
If you’re using simple balancing, make sure the schedule queue is defined early as that determines priority.
User model
If you use your own User model, make sure to replace the one in config/mailcoach.php
with your own:
'models' => [ ... - 'user' => \Spatie\Mailcoach\Domain\Settings\Models\User::class, + 'user' => \App\Models\User::class, ... ]
The standalone starter project defined the Auth user model as \Spatie\MailcoachUi\Models\User
, replace this with the new User model, or your own model in config/auth.php
.
'users' => [ 'driver' => 'eloquent', - 'model' => Spatie\MailcoachUi\Models\User::class, + 'model' => \Spatie\Mailcoach\Domain\Settings\Models\User::class, ],
Views
Delete the resources/views/vendor/mailcoach
folder if you did not have any changes made to the views.
Otherwise, we recommend deleting the folder anyway and re-publishing to port over any of your changes.
Run php artisan view:clear
to delete any compiled views.
Migration changes
There have been a few additions and changes to the Mailcoach tables, you can use the migration below to update your database:
Some notable changes:
- All models now have a UUID
- Custom confirmation mails now use transactional mails instead of raw html
Make sure you have doctrine/dbal
installed in your app for rename migrations to work.
composer require doctrine/dbal
You’ll find the upgrade to v6 migration here
Depending on how much data you have this could take a long time. It might be a good idea to split this up into separate migrations.
If you’re already using Laravel MediaLibrary make sure that the media
table in your project has the same fields as the media
migration included with Mailcoach.
Open & Click tracking
The Campaign, AutomationMail and TransactionalMail no longer have the ability to enable/disable open & click tracking.
This is because this is a setting at the provider level that Mailcoach has no direct control over. You could disable tracking in Mailcoach but still have tracking links & pixels present because the settings was enabled at your provider.
When setting up mailers through the new mailer UI, Mailcoach will make the necessary API calls to enable/disable tracking for that provider.
Transactional models renamed
The Spatie\Mailcoach\Domain\TransactionalMail\Models\TransactionalMail
model has been renamed to Spatie\Mailcoach\Domain\TransactionalMail\Models\TransactionalMailLogItem
The Spatie\Mailcoach\Domain\TransactionalMail\Models\TransactionalMailTemplate
model has been renamed to Spatie\Mailcoach\Domain\TransactionalMail\Models\TransactionalMail
Make sure to rename these in the correct order if you reference these inside your application.
Translations
We’ve reworked how Mailcoach translations work, if you had published them make sure to republish the translations.
If you referenced Mailcoach translations somewhere in your app, make sure to replace it by the new helper, the mailcoach -
prefix is no longer necessary:
- {{ __('mailcoach - Some translation string') }} + {{ __mc('Some translation string') }} - {{ trans_choice('mailcoach - One|More', 2) }} + {{ __mc_choice('One|More', 2) }}
API
All API resources & endpoints now use uuid
s instead of id
s for references to models. Update your integrations with the API if necessary.
Unlayer users
This version of Mailcoach uses an newer version of Unlayer. Your old templates might not be compatible. To make Unlayer templates compatible, you might try the code mentioned in this issue. Also take look at this issue
If you still reference Route::mailcoachUnlayer()
somewhere in project, you should remove it.