Voyager框架:管理员添加用户时如何自动发送用户信息邮件?
Great question! When working with Voyager's admin panel, there are a couple of straightforward ways to trigger a welcome email when a new user is created via the User page—no need for complex hacks. Let me walk you through the two most reliable methods, including how to handle the plaintext password (since Voyager automatically hashes it on save):
Method 1: Use Model Events (Simplest Approach)
This method leverages Laravel's model lifecycle events to hook into user creation, and we'll capture the plaintext password before it gets hashed.
Step 1: Update Your User Model
Open your app/Models/User.php file and add the following code to the class. We'll use the creating event to store the plaintext password temporarily, then the created event to send the email:
<?php namespace App\Models; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Illuminate\Support\Facades\Mail; use App\Mail\WelcomeNewUser; class User extends Authenticatable { use Notifiable; // Temporary property to hold plaintext password protected $plainPassword; /** * The attributes that are mass assignable. * * @var array<int, string> */ protected $fillable = [ 'name', 'username', 'email', 'password', ]; /** * The attributes that should be hidden for serialization. * * @var array<int, string> */ protected $hidden = [ 'password', 'remember_token', ]; /** * The attributes that should be cast. * * @var array<string, string> */ protected $casts = [ 'email_verified_at' => 'datetime', 'password' => 'hashed', ]; protected static function boot() { parent::boot(); // Capture plaintext password before it's hashed static::creating(function ($user) { if (request()->has('password')) { $user->plainPassword = request()->input('password'); } }); // Send welcome email after user is created static::created(function ($user) { // Only send if we have a plaintext password AND the request comes from the admin panel if (isset($user->plainPassword) && request()->is('admin/*')) { Mail::to($user->email)->send(new WelcomeNewUser($user, $user->plainPassword)); } }); } }
Step 2: Create the Welcome Email Class
Run this Artisan command to generate a new mailable:
php artisan make:mail WelcomeNewUser
Open app/Mail/WelcomeNewUser.php and update it to accept the user and plaintext password:
<?php namespace App\Mail; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Mail\Mailable; use Illuminate\Queue\SerializesModels; use App\Models\User; class WelcomeNewUser extends Mailable { use Queueable, SerializesModels; public $user; public $plainPassword; /** * Create a new message instance. */ public function __construct(User $user, string $plainPassword) { $this->user = $user; $this->plainPassword = $plainPassword; } /** * Build the message. * * @return $this */ public function build() { return $this->subject('Welcome to Our Platform') ->view('emails.welcome'); } }
Step 3: Create the Email View
Create a new blade file at resources/views/emails/welcome.blade.php with your desired welcome content:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Welcome Aboard!</title> </head> <body> <h2>Welcome "{{ $user->name }}"!</h2> <p>Your account has been created successfully. Here are your login details:</p> <ul> <li><strong>Username:</strong> {{ $user->username }}</li> <li><strong>Password:</strong> {{ $plainPassword }}</li> </ul> <p>Feel free to reach out if you need help!</p> </body> </html>
Method 2: Override Voyager's User Controller (More Control)
If you want full control over the admin user creation flow, you can override Voyager's built-in User Controller:
Step 1: Create a Custom Admin User Controller
Make a new controller at app/Http/Controllers/Admin/UserController.php that extends Voyager's User Controller:
<?php namespace App\Http\Controllers\Admin; use Illuminate\Http\Request; use TCG\Voyager\Http\Controllers\VoyagerUserController as BaseController; use Illuminate\Support\Facades\Mail; use App\Mail\WelcomeNewUser; class UserController extends BaseController { public function store(Request $request) { // Capture the plaintext password before saving $plainPassword = $request->input('password'); // Let Voyager handle saving the user (including password hashing) $response = parent::store($request); // Fetch the newly created user $user = $this->dataType->model::find($this->getLastInsertId()); // Send the welcome email Mail::to($user->email)->send(new WelcomeNewUser($user, $plainPassword)); return $response; } // Helper to get the last inserted user ID protected function getLastInsertId() { return app('db')->getPdo()->lastInsertId(); } }
Step 2: Update Routes to Use Your Custom Controller
In routes/web.php, add this route group after Voyager's default routes to override the user management routes:
Route::group(['prefix' => 'admin'], function () { Voyager::routes(); // Override Voyager's user routes with our custom controller Route::resource('users', \App\Http\Controllers\Admin\UserController::class)->names([ 'index' => 'voyager.users.index', 'create' => 'voyager.users.create', 'store' => 'voyager.users.store', 'show' => 'voyager.users.show', 'edit' => 'voyager.users.edit', 'update' => 'voyager.users.update', 'destroy' => 'voyager.users.destroy', ]); });
Final Notes
- Mail Configuration: Make sure your
.envfile has correct mail settings (e.g.,MAIL_MAILER,MAIL_HOST,MAIL_USERNAME,MAIL_PASSWORD) so emails can be sent. - Queueing Emails: For better performance, consider queueing the email instead of sending it synchronously. Just implement
ShouldQueueon yourWelcomeNewUsermailable and set up a queue driver. - Frontend Registration: Your existing
RegisterControllercan handle welcome emails for frontend signups separately—this setup only triggers for admin-created users.
内容的提问来源于stack exchange,提问作者Ali Öz

