Laravel-Permission インストール

**・参考**
[laravel-permissionの使い方](https://qiita.com/beeete2/items/0cb2ee0e6341c9be7075)

##1. Laravel のインストール
[Laravel5.5 インストール](https://qiita.com/Fell/private/dfe24647f16637807e88)

##2. authのインストールとDBマイグレーション

```php:migration
//Laravel6では変更になりましたね。
$ php artisan make:auth
```
login Register のボタンを右上に確認。

####2-1. laravel-permission を composerからインストール
Laravel5.7以下 -> v2
Laravel5.8以上 -> v3

```php:Laravel-permission
//今回はLaravel5.5なのでv2をインストール
$ composer require spatie/laravel-permission:2.*
```

####2-2. app/Http/Kernel.php に追記

```php:app/Http/Kernel.php
60行目前後

protected $routeMiddleware = [
    ....
    'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class,
    'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class,
    'role_or_permission' => \Spatie\Permission\Middlewares\RoleOrPermissionMiddleware::class,
]
....
```
####2-3. app/User.php (app/Models/User.php) に追記
```php:app/User.php
....
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
    ....
    use HasRoles;
    ]
}
````

###3. DBテーブルのマイグレーション
artisanコマンドで マイグレーションファイルを生成します

```php:migration-DBテーブル
$ php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="migrations"
```

２つのファイルが作成されます。
./database/migrations/2018_07_31_072708_create_permission_tables.php
./bootstrap/cache/services.php


###4. コンフィグファイルのマイグレーション

```php:migration-config
$ php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="config"
```
次の1ファイルが作成されます

./config/permission.php
###5. DBテーブルの作成

```php:migration
$ php artisan migrate
```

5つのDBテーブルが作成されます。
model_has_permissions
model_has_roles
permissions
roles
role_has_permissions

###6.DBデータの作成
####6-1. PermissionTableSeeder.php 
シーダー雛形作成
```$ php artisan make:seeder PermissionTableSeeder```

```php:app/database/seeds/PermissionTableSeeder.php
<?php
use Illuminate\Database\Seeder;
use Spatie\Permission\Models\Permission;//追加

class PermissionTableSeeder extends Seeder
{
	public function run()
	{
        //追加
		$permissions = [
			'admin_permission',
			'manager_permission',
			'staff_permission',
			'customer_permission',
		];
		foreach ($permissions as $permission) {
			Permission::create(['name' => $permission]);
		}
	}
}
```
シーダーの実行
```$ php artisan db:seed --class=PermissionTableSeeder```

####6-2. RoleTableSeeder.php 準備
シーダー雛形作成
```$ php artisan make:seeder RoleTableSeeder```

```php:app/database/seeds/RoleTableSeeder.php
<?php
use Illuminate\Database\Seeder;
use Spatie\Permission\Models\Role;//追加
class RoleTableSeeder extends Seeder
{
    public function run()
    {
        //追加
        $roles = [
            'admin',
            'manager',
            'staff',
            'customer',
        ];
        foreach ($roles as $role) {
            Role::create(['name' => $role]);
        }
    }
}
```
シーダーの実行
```$ php artisan db:seed --class=RoleTableSeeder```
####6-3. RoleHasPermissionTableSeeder.php 準備
シーダー雛形作成
```$ php artisan make:seeder RoleHasPermissionTableSeeder```

```php:app/database/seeds/RoleHasPermissionTableSeeder.php
<?php
use Illuminate\Database\Seeder;
use Spatie\Permission\Models\Permission;//追加
use Spatie\Permission\Models\Role;//追加
class RoleHasPermissionTableSeeder extends Seeder
{
	public function run()
	{
        //追加
        // admin
		$permissions = [
			'admin_permission',
			'manager_permission',
			'staff_permission',
		];
		$role = Role::findByName('admin');
		$role->givePermissionTo($permissions);

		// manager
		$permissions = [
			'manager_permission',
			'staff_permission',
		];
		$role = Role::findByName('manager');
		$role->givePermissionTo($permissions);

		// staff
		$permissions = [
			'staff_permission',
		];
		$role = Role::findByName('staff');
		$role->givePermissionTo($permissions);	

		// customer
		$permissions = [
			'customer_permission',
		];
		$role = Role::findByName('customer');
		$role->givePermissionTo($permissions);	
	}
}
```
シーダーの実行
```$ php artisan db:seed --class=RoleHasPermissionTableSeeder```

###4. UserTableSeeder.php 準備
シーダー雛形作成
```$ php artisan make:seeder UserTableSeeder```

```php:app/database/seeds/UserTableSeeder.php
<?php
use App\User;
use Illuminate\Database\Seeder;
class UserTableSeeder extends Seeder
{
	public function run()
	{
        //追加
		// admin
		$user = User::create([
			'name'     => 'web管理責任者',
			'email'    => 'admin@gmail.com',
			'password' => Hash::make('admin'),
		]);
		$user->assignRole('admin');
		// manager
		$user = User::create([
			'name'     => 'サイトマネージャ',
			'email'    => 'manager@gmail.com',
			'password' => Hash::make('manager'),
		]);
		$user->assignRole('manager');
		// staff
		$user = User::create([
			'name'     => 'スタッフ',
			'email'    => 'staff@gmail.com',
			'password' => Hash::make('staff'),
		]);
		$user->assignRole('staff');	
		// customer
		$user = User::create([
			'name'     => 'カスタマー',
			'email'    => 'customer@gmail.com',
			'password' => Hash::make('customer'),
		]);
		$user->assignRole('customer');	
	}
}
```
シーダーの実行
```$ php artisan db:seed --class=UserTableSeeder```

###5. シーダーのやり直し
```$ php artisan migrate:rollback --step=1```

####メソッド一覧
######Permission
```php:
public static    create(array $attributes = [])
public           roles(): BelongsToMany
public           users(): MorphToMany
public static    findByName(string $name, $guardName = null): PermissionContract
public static    findById(int $id, $guardName = null): PermissionContract
public static    findOrCreate(string $name, $guardName = null): PermissionContract
protected static getPermissions(): Collection
```
######Role
```php:
public static    create(array $attributes = [])
public           permissions(): BelongsToMany
public           users(): MorphToMany
public static    findByName(string $name, $guardName = null): RoleContract
public static    findById(int $id, $guardName = null): RoleContract
public static    findOrCreate(string $name, $guardName = null): RoleContract
public           hasPermissionTo($permission): bool
```
**Userモデルなど既存のモデルに追加される拡張メソッド**
*use HasRoles* で拡張されるメソッド

```php:
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
    use HasRoles;
    ..........
```

```php:
//auth()->user()->{method}
public static        bootHasRoles()
public       roles(): MorphToMany
public       scopeRole(Builder $query, $roles): Builder
public       assignRole(...$roles)
public       removeRole($role)
public       syncRoles(...$roles)
public       hasRole($roles): bool
public       hasAnyRole($roles): bool
public       hasAllRoles($roles): bool
public       getDirectPermissions(): Collection
public       getRoleNames(): Collection
protected        getStoredRole($role): Role
protected        convertPipeToArray(string $pipeString)
```
**・Controllerでの例**

```php:app\Http\Controllers\HomeController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;

class HomeController extends Controller
{
---
    public function index() {
        //ログインユーザーの role を取得
        echo auth()->user()->getRoleNames(); //["customer"]
    }
}
```

*use HasPermissions* で拡張されるメソッド

```php:
use Spatie\Permission\Traits\HasPermissions;
class User extends Authenticatable
{
    use HasPermissions;
    ..........
```

```php:
public static        bootHasPermissions()
static::deleting(        ($model) {
public       permissions(): MorphToMany
public       scopePermission(Builder $query, $permissions): Builder
protected        convertToPermissionModels($permissions): array
public       hasPermissionTo($permission, $guardName = null): bool
public       hasAnyPermission(...$permissions): bool
public       hasAllPermissions(...$permissions): bool
protected        hasPermissionViaRole(Permission $permission): bool
public       hasDirectPermission($permission): bool
public       getPermissionsViaRoles(): Collection
public       getAllPermissions(): Collection
public       givePermissionTo(...$permissions)
public       syncPermissions(...$permissions)
public       revokePermissionTo($permission)
protected        getStoredPermission($permissions)
protected        ensureModelSharesGuard($roleOrPermission)
protected        getGuardNames(): Collection
protected        getDefaultGuardName(): string
public       forgetCachedPermissions()
```
######● Bladeビューでの権限(Permission)判定
Permission を判別。

```php:
<p>
    @can('admin_permission')
        admin_permission を持っています <br>
    @endcan

    @can('manager_permission')
        manager_permission を持っています <br>
    @endcan

    @can('staff_permission')
     staff_permission を持っています <br>
    @endcan
</p>
```
######● Bladeビューでのロール（Role）判定
Role を判別。

```php:
<p>
    @hasrole('manager')
        managerの役割をもっています。
    @else
        managerの役割を持っていません。
    @endhasrole                    

    @role('staff')
        あなたはstaffの役割を持っています。
    @elserole('customer')
        あなたはcustomerの役割を持っています。
    @else
        役割を持っていません。
    @endrole                    
</p>
```
######● Routes での権限、ロール判定

```php:app/Http/Kernel.php 
63行目前後
protected $routeMiddleware = [
    // ...
    'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class,
    'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class,
    'role_or_permission' => \Spatie\Permission\Middlewares\RoleOrPermissionMiddleware::class,
];
```
*Routes* 設定

```php:App/routes/web.php

// 誰でもアクセス可能
Route::resource('users', 'UserController');

// 「ログイン」している時のみアクセス可能
Route::group(['middleware' => ['auth']], function() {
    Route::resource('users', 'UserController');
});

// 「ログイン」かつ「admin_permissionを持つ」時のみアクセス可能
Route::group(['middleware' => ['auth', 'permission:admin_permission']], function() {
    Route::resource('users', 'UserController');
});
```
LGTMお願いします！
モチベーションがあがります！