Laravel 5.3 - Лучший способ реализовать роль Entrust при регистрации?

Я работаю с Laravel 5.3 и я пытаюсь установить роль, когда кто-то подписывается, я использовал Zizaco Entrust библиотека.

Я не уверен, как лучше всего добиться чего-то подобного.

Я пытался сделать это внутри RegisterController"s 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);
}

Но очевидно, что это не так. Так что я немного не уверен в том, что лучше всего делать с подобными вещами.

3 ответа

Решение

Если, как следует из вашего комментария к OP, вы всегда хотите назначить одну и ту же роль зарегистрированному пользователю, вы можете использовать для этого Model Observer - это действительно просто.

// app/Observers/UserObserver.php

<?php namespace App\Observers;

use App\Models\User;
use App\Models\Role; // 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 App\Models\User;
use App\Observers\UserObserver;

class AppServiceProvider extends Provider {

    public function boot() {
        User::observe( new UserObserver );
        // ...
    }

    // ...

}

Этот ответ в основном основан на взгляде на ваше текущее решение с чертой оригинального вопроса.

Вместо того, чтобы заполнять вашу модель такими методами, как createNewвам, вероятно, будет легче управлять, если вы создадите тип класса специально для взаимодействия с моделями. Вы можете называть это репозиторием или службой или как угодно, но мы будем работать со службой.

// app/Services/UserService.php

<?php namespace App\Services;

use App\Models\User; // 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 App\Events;

use App\Models\User;
use Illuminate\Queue\SerializesModels;

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 App\Listeners;

use App\Events\UserHasRegistered;
use App\Services\NotificationService;

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, что Event и Listener, который мы только что создали, связаны между собой, а затем запустить событие.

// app/Providers/EventServiceProvider.php

use App\Events\UserHasRegistered;
use App\Listeners\SendUserWelcomeEmail;

class EventServiceProvider extends ServiceProvider {

    // find this array near the top, and add this in
    protected $listen = [
        UserHasRegistered::class => [
            SendUserWelcomeEmail::class,
        ],
    ];

    // ...

}

Теперь нам просто нужно поднять событие - см. Мой другой пост о Model Observers. Прежде всего вам нужно будет импортировать Event а также App\Events\UserHasRegisteredтогда в вашем 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);

Возможно, это не лучшее решение, но оно делает свою работу, и это будущий профит, поэтому, если логика создания пользователя будет расти, она также может быть реализована.

Другие вопросы по тегам