我正在使用Laravel 5.3
,当有人注册时,我试图设置一个角色,我已经使用了Zizaco Entrust
库。
我不确定实现这一目标的最佳方法。
我尝试在RegisterController
的create
方法中这样做,如下所示:
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
$user = User::where('email', '=', $data['email'])->first();
// role attach alias
$user->attachRole($employee);
}
但显然这是不对的。所以我有点不确定这类事情的最佳实践是什么
如果,正如您对OP的评论所建议的那样,您总是希望将相同的角色分配给注册用户,您可以为此使用模型观察者-这真的很简单。
// app/Observers/UserObserver.php
<?php namespace AppObservers;
use AppModelsUser;
use AppModelsRole; // or the namespace to the Zizaco Role class
class UserObserver {
public function created( User $user ) {
$role = Role::find( 1 ); // or any other way of getting a role
$user->attachRole( $role );
}
然后你只需在AppServiceProvider中注册观察者:
// app/Providers/AppServiceProvider.php
use AppModelsUser;
use AppObserversUserObserver;
class AppServiceProvider extends Provider {
public function boot() {
User::observe( new UserObserver );
// ...
}
// ...
}
这个答案主要基于你当前的解决方案,并带有一些原始问题。
与其用createNew
这样的方法填充模型,不如创建专门用于与模型交互的类类型,您可能会发现管理起来更容易。你可以称它为Repository或Service或任何你喜欢的名称,但我们将使用Service来运行。
// app/Services/UserService.php
<?php namespace AppServices;
use AppModelsUser; // or wherever your User model is
class UserService {
public function __construct( User $user ) {
$this->user = $user;
}
public function create( array $attributes, $role = null ) {
$user = $this->user->create( $attributes );
if ( $role ) {
$user->attachRole( $role );
}
return $user;
}
}
现在我们需要处理丢失了密码散列的事实:
// app/Models/User.php
class User ... {
public function setPasswordAttribute( $password ) {
$this->attributes[ 'password' ] = bcrypt( $password );
}
}
现在我们有发送激活电子邮件的问题——这个问题可以用事件来解决。在终端中运行以下命令:
php artisan make:event UserHasRegistered
应该是这样的:
// app/Events/UserHasRegistered.php
<?php namespace AppEvents;
use AppModelsUser;
use IlluminateQueueSerializesModels;
class UserHasRegistered extends Event {
use SerializesModels;
public $user;
public function __construct( User $user ) {
$this->user = $user;
}
}
现在我们需要一个事件的监听器:
php artisan make:listener SendUserWelcomeEmail
这个可以很复杂,这是我从一个项目中复制/粘贴过来的
// app/Listeners/SendUserWelcomeEmail.php
<?php namespace AppListeners;
use AppEventsUserHasRegistered;
use AppServicesNotificationService;
class SendUserWelcomeEmail {
protected $notificationService;
public function __construct( NotificationService $notificationService ) {
$this->notify = $notificationService;
}
public function handle( UserHasRegistered $event ) {
$this->notify
->byEmail( $event->user->email, 'Welcome to the site', 'welcome-user' )
->send();
}
}
剩下的就是告诉Laravel我们刚刚创建的事件和监听器是相关的,然后触发事件。
// app/Providers/EventServiceProvider.php
use AppEventsUserHasRegistered;
use AppListenersSendUserWelcomeEmail;
class EventServiceProvider extends ServiceProvider {
// find this array near the top, and add this in
protected $listen = [
UserHasRegistered::class => [
SendUserWelcomeEmail::class,
],
];
// ...
}
现在我们只需要引发事件-参见我关于模型观察者的另一篇文章。首先,您需要导入Event
和AppEventsUserHasRegistered
,然后在created
方法中,只需调用Event::fire( new UserHasRegistered( $user ) )
。
由于我确实需要对用户创建做不止一个操作,所以我最终做的是为用户创建创建另一个函数。
用户模型
/**
* Create a new user instance after a valid registration.
*
* @param array $attributes
* @param null $role
* @param bool $send_activation_email
*
* @return User $user
*
* @internal param array $args
*/
public function createNew(array $attributes, $role = null, $send_activation_email = true)
{
$this->name = $attributes['name'];
$this->company_id = $attributes['company_id'];
$this->email = $attributes['email'];
$this->password = bcrypt($attributes['password']);
$this->save();
if (isset($role)) {
// Assigning the role to the new user
$this->attachRole($role);
}
//If the activation email flag is ok, we send the email
if ($send_activation_email) {
$this->sendAccountActivationEmail();
}
return $this;
}
并像这样调用它:
用户控制器
$user = new User();
$user->createNew($request->all(), $request->role);
这可能不是最好的解决方案,但它完成了工作,并且它是未来的prof,所以如果用户创建的逻辑增长也可以实现。