I implemented this workaround for adding a button to a standard SimpleMail
object. Since MailMessage::line()
can accept any object that implements Htmlable
, you can put anything you want in it.
You still have to override the notification class to instead create an instance of MyMultiButtonVerifyEmail
(instead of VerifyEmail
), but that's easily done (and something you probably already had to do once updated email copy was provided).
Grrr, these default Laravel notification classes are not really reusable, are they?
use Illuminate\Auth\Notifications\VerifyEmail;
use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Notifications\Action;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Support\Facades\Lang;
class MyMultiButtonVerifyEmail extends VerifyEmail {
public function toMail($notifiable) {
$verificationUrl = ...;
$resendUrl = ...;
return (new MailMessage)
->line('some line')
->action(Lang::getFromJson('Verify Email Address'), $verificationUrl)
->line('another line')
->line($this->makeActionIntoLine(new Action(Lang::getFromJson('Request New Activation'), $resendUrl)))
->line(Lang::getFromJson('If you did not create an account, no further action is required.'));
} // end toMail()
private function makeActionIntoLine(Action $action): Htmlable {
return new class($action) implements Htmlable {
private $action;
public function __construct(Action $action) {
$this->action = $action;
} // end __construct()
public function toHtml() {
return $this->strip($this->table());
} // end toHtml()
private function table() {
return sprintf(
'<table class="action">
<tr>
<td align="center">%s</td>
</tr></table>
', $this->btn());
} // end table()
private function btn() {
return sprintf(
'<a
href="%s"
class="button button-primary"
target="_blank"
style="font-family: -apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, Helvetica, Arial, sans-serif, \'Apple Color Emoji\', \'Segoe UI Emoji\', \'Segoe UI Symbol\'; box-sizing: border-box; border-radius: 3px; box-shadow: 0 2px 3px rgba(0, 0, 0, 0.16); color: #fff; display: inline-block; text-decoration: none; -webkit-text-size-adjust: none; background-color: #3490dc; border-top: 10px solid #3490dc; border-right: 18px solid #3490dc; border-bottom: 10px solid #3490dc; border-left: 18px solid #3490dc;"
>%s</a>',
htmlspecialchars($this->action->url),
htmlspecialchars($this->action->text)
);
} // end btn()
private function strip($text) {
return str_replace("\n", ' ', $text);
} // end strip()
};
} // end makeActionIntoLine()
}
For posterity, this was written for Laravel 5.8.32. There may be better ways of accomplishing this in later versions of the framework. YMMV.