Continuamos con la sección de roles y permisos en Laravel. Esta parte va a ser un poco densa, ya que vamos a hacer bastantes cosas. Crearemos una mini administración de usuarios y podremos cambiar su rol, podremos activar y desactivar usuarios. Todo esto, podremos hacerlo si nuestro usuario tiene el rol administrator.
Primero vamos a empezar creando el controlador. Como siempre, utilizaremos el comando que nos provee Laravel.
1 |
php artisan make:controller Admin\UsersController |
Y añadimos este código:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
<?php namespace App\Http\Controllers\Admin; use Illuminate\Http\Request; use App\Http\Controllers\Controller; use Illuminate\Support\Facades\Auth; use App\User; use Spatie\Permission\Models\Role; class UsersController extends Controller { public function index() { $users = User::all(); $roles = Role::pluck('name', 'name'); return view('admin.users.index', ['users' => $users, 'roles' => $roles]); } public function activeDeactive(Request $request) { if (Auth::id() != $request->user_id) { $user = User::findOrFail($request->user_id); $user->active = !$user->active; $user->save(); return redirect()->route("admin.users.index")->with('success', $user->name." status has been changed!"); } else { return redirect()->back()->withErrors(['You can\'t change your status!']); } } public function changeRole(Request $request) { if (Auth::id() != $request->user_id) { $user = User::findOrFail($request->user_id); $user->syncRoles($request->role); return redirect()->route("admin.users.index")->with('success', $user->name." role has been changed!"); } else { return redirect()->back()->withErrors(['You can\'t change your role!']); } } } |
Tiene 3 métodos:
- index: envía a la vista la lista de usuarios. Y también los roles para mostrar en el popup para cambiar el rol.
- activeDeactive: activa y desactiva del usuario indicado.
- changeRole: cambia el rol del usuario indicado.
Creamos la vista para la lista de usuarios y el popup para el cambio de rol (método index):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
@extends('layouts.app') @section('content') <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <h3>User list</h3> @include('includes.errors') @if(session()->has('success')) <div class="alert alert-success"> {{ session()->get('success') }} </div> @endif <table class="table table-bordered table-striped"> <thead> <tr> <th>#</th> <th>Name</th> <th>Email</th> <th>Role</th> <th>Options</th> </tr> </thead> <tbody> @forelse ($users as $user) <tr class="{{ ($user->active == 0) ? 'danger' : '' }}"> <td>{{ $user->id }}</td> <td>{{ $user->name }}</td> <td>{{ $user->email }}</td> <td> @foreach ($user->roles()->pluck('name') as $role) <span class="label label-default">{{ $role }}</span> @endforeach </td> <td> @if (Auth::id() != $user->id) <button type="button" class="btn-modal-change-role btn btn-info btn-sm" data-userid="{{ $user->id }}" data-userrole="{{ $role }}">Change role</button> {{ Form::open(['route' => ['admin.users.active_deactive'], 'method' => 'POST']) }} {{ Form::hidden('user_id', $user->id) }} {{ Form::submit(($user->active == 0) ? 'Reactive' : 'Deactivate', ['name' => 'submit', 'class' => 'btn btn-warning btn-sm']) }} {{ Form::close() }} @endif </td> </tr> @empty <tr> <td colspan="5">No results</td> </tr> @endforelse </tbody> </table> </div> </div> </div> <div class="modal fade" id="roleModal" role="dialog"> <div class="modal-dialog modal-sm"> <div class="modal-content"> <div class="modal-header"> <h3>Change role</h3> </div> <div class="modal-body"> {{ Form::open(['route' => ['admin.users.change_role'], 'method' => 'POST']) }} {{ Form::hidden('user_id') }} <p>{{ Form::select('role', $roles, null, ['class' => 'form-control']) }}</p> {{ Form::submit('Change', ['name' => 'submit', 'class' => 'btn btn-success btn-block btn-change-role']) }} {{ Form::close() }} </div> </div> </div> </div> @endsection |
Ahora vamos a añadir las rutas para estos métodos, pero primero vamos a crear un middleware para comprobar que tiene el rol administrator:
1 |
php artisan make:middleware RoleMiddleware |
Y añadimos este código, podemos encontrarlo en la documentación del paquete:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Support\Facades\Auth; class RoleMiddleware { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next, $role = null, $permission = null ) { if (Auth::guest()) { return Redirect::guest('login'); } if (!$request->user()->hasRole($role)) { abort(403); } if ($permission != null && !$request->user()->can($permission)) { abort(403); } return $next($request); } } |
Lo registramos:
1 2 3 4 |
protected $routeMiddleware = [ ... 'role' => \App\Http\Middleware\RoleMiddleware::class, ]; |
Y con esto ya lo podemos añadir en las rutas con el middleware:
1 2 3 4 5 |
Route::group(['middleware' => ['auth', 'role:administrator'], 'prefix' => 'admin', 'as' => 'admin.'], function () { Route::get('/users', 'Admin\UsersController@index')->name('users.index'); Route::post('/users/active_deactive', 'Admin\UsersController@activeDeactive')->name('users.active_deactive'); Route::post('/users/change_role', 'Admin\UsersController@changeRole')->name('users.change_role'); }); |
Ahora vamos a añadir en el header el link para la administración:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
@role('administrator') <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"> Administration <span class="caret"></span> </a> <ul class="dropdown-menu" role="menu"> <li> <a href="{{ route('admin.users.index') }}"> Users </a> </li> </ul> </li> @endrole |
Solamente se muestra si tienes el rol administrator, eso se hace con la etiqueta @role.
Abrimos el app.js y añadimos este código para mostrar el popup de cambio de rol:
1 2 3 4 5 6 7 8 9 10 11 |
$(document).ready(function(){ $(".btn-modal-change-role").click(function(e) { var currentUserRole = $(this).data("userrole"); var currentUserId = $(this).data("userid"); // add the user id of the selected user to the input $("input[name='user_id']").val(currentUserId); // select current role for the user selected $("select[name='role']").val(currentUserRole); $("#roleModal").modal("show"); }); }); |
Y ejecutamos este comando, para que se actualice el js de la carpeta public que es el que se incluye en el layout:
1 2 3 4 5 |
//si estamos en desarollo npm run dev //si estamos en producción npm run prod |
El resultado sería ésto:
En que parte del app.js se agrega el codigo? por que no sale la animacion y corri el npm de las dos maneras pero no hace la animacion ni hace el cambio
Hola,
Yo lo agregué al final.
Yo creo que te debe faltar algún código o lo has puesto en un sitio equivocado o algo. Mira que tengas integrado Bootstrap y jQuery y que el código esté bien. Mira también a ver que te dice la consola JS si te da algún error o algo (pulsa F12 para ver la consola).
Un saludo!
Hola, buenas tardes, estoy siguiendo su tutorial pero me sale un error
Symfony \ Component \ Debug \ Exception \ FatalThrowableError (E_ERROR)
Class ‘Spatie\Permission\Models\Role’ not found
No se a que se deba, usted no lo menciona y parece correr a la primera.
Gracias
Hola Kevin,
Gracias por tu comentario.
Tienes instalado el paquete laravel-permissions?
El error que te da es que no encuentra la clase Role («Class ‘Spatie\Permission\Models\Role’ not found») y posiblemente sea porque no tengas instalado ese paquete.
Puedes ver como hacerlo en este post: http://fullstackseries.com/laravel-5-4-19-roles-permisos-parte-1/
Saludos!
Gran Post
Muchas gracias por tu comentario.
Gracias por este post tan fantastico!