lunes, 7 de diciembre de 2015

23 - Tutorial de Laravel 5 - Admin Panel (Panel de Administrador)




En este capítulo del Tutorial de Laravel 5 veremos un supuesto en el cual tenemos que crear un Panel de Administrador. La condición de administrador o no, la realizaremos desde la tabla users, para esta tarea crearemos una nueva columna llamada "user" del tipo integer y con un valor por defecto 0, el valor de esta columna nos determinará el tipo de usuario del que se trata, 0 para usuario normal y 1 para usuario administrador.


Empezaremos con el uso de artisan para realizar la migración, primero generaremos la clase, abrir una consola, dirigirnos a la raiz de nuestro proyecto e introducir el siguiente comando ...


php artisan make:migration add_user_to_users


Una vez se ha generado el archivo, nos dirigimos a "database\migrations" y abrimos el archivo xxx_add_user_to_users.php e incluimos el siguiente código dentro del método up() para crear la nueva columna ...


        Schema::table('users', function($table){
            $table->integer('user')->default(0);
        });


A continuación regresamos a la consola y realizamos la migración ...


php artisan migrate


Ok, ya tenemos la nueva columna "user" en la tabla "users".


Para el acceso al panel de administrador crearemos un nuevo controlador "AdminController", el controlador lo crearemos con artisan, desde la consola ...


php artisan make:controller AdminController


Nos dirigimos al nuevo controlador que se encuentra en "app\Http\Controllers" y dejamos la clase vacía, es decir, quitamos todos los métodos que se incluyen por defecto e importamos las siguientes clases ...


use App\User;
use Validator;
use Auth;


A continuación crearemos una acción-ruta "createAdmin" que permitirá al propietario de la aplicación crear un administrador o administradores, esta acción-ruta ha de ser usada y posteriormente comentada para evitar el acceso a cualquier usuario ...


Agregar el código de la acción "createAdmin" al controlador AdminController ...


public function createAdmin(Request $request){
  
  if ($request->isMethod('post'))
  {
   //Roles de validación
   $rules = [
    'name' => 'required|min:3|max:16|regex:/^[a-záéíóúàèìòùäëïöüñ\s]+$/i',
    'email' => 'required|email|max:255|unique:users,email',
    'password' => 'required|min:6|max:18|confirmed',
   ];
   
   //Posibles mensajes de error de validación
   $messages = [
    'name.required' => 'El campo es requerido',
    'name.min' => 'El mínimo de caracteres permitidos son 3',
    'name.max' => 'El máximo de caracteres permitidos son 16',
    'name.regex' => 'Sólo se aceptan letras',
    'email.required' => 'El campo es requerido',
    'email.email' => 'El formato de email es incorrecto',
    'email.max' => 'El máximo de caracteres permitidos son 255',
    'email.unique' => 'El email ya existe',
    'password.required' => 'El campo es requerido',
    'password.min' => 'El mínimo de caracteres permitidos son 6',
    'password.max' => 'El máximo de caracteres permitidos son 18',
    'password.confirmed' => 'Los passwords no coinciden',
   ];
   
   $validator = Validator::make($request->all(), $rules, $messages);
   
   //Si la validación no es correcta redireccionar al formulario con los errores
   if ($validator->fails()){
    return redirect()->back()->withErrors($validator);
   }
   else{ // De los contrario guardar al usuario
    $user = new User;
    $user->name = $request->name;
    $user->email = $request->email;
    $user->password = bcrypt($request->password);
    $user->remember_token = str_random(100);
    $user->confirm_token = str_random(100);
    //Activar al administrador sin necesidad de enviar correo electrónico
    $user->active = 1;
    //El valor 1 en la columna determina si el usuario es administrador o no
    $user->user = 1;
    
    if ($user->save()){
     return redirect()->back()->with('message', 'Enhorabuena nuevo administrador creado correctamente');
    } else{
     return redirect()->back()->with('error', 'Ha ocurrido un error al guardar los datos');
    }
   }
  }
  
  return View('admin.createadmin');
 }


Esta acción estará disponible tanto para los métodos get y post, get para mostrar la vista "createadmin" que contiene el formulario de registro de administradores y post para recibir los argumentos del formulario. Si el formulario es enviado se valida, si pasa la validación se registra el nuevo usuario activándolo y con permisos de administrador.


A continuación creamos una nueva ruta para asociarla a esta acción en routes.php ...

Route::match(['get', 'post'], 'admin/createadmin', 'AdminController@createAdmin');


Y creamos una nueva carpeta para las vistas del controlador "AdminController", en "resources\views", creamos una carpeta con nombre "admin" y agregamos la vista "createadmin.blade.php" que contiene el formulario de registro de administradores, el código es el siguiente ...

@extends('layouts.home')
@section('content')
<h1>Crear un nuevo administrador</h1>
<div class='bg-danger' style='padding: 20px'>¡¡¡Una vez termines de crear el administrador desactiva esta acción-ruta!!!</div>
<hr />
@if (Session::has('message'))
 <div class='bg-info' style='padding: 20px'>
  {{Session::get('message')}}
 </div>
 <hr />
@endif
@if (Session::has('error'))
 <div class='bg-danger' style='padding: 20px'>
  {{Session::get('error')}}
 </div>
 <hr />
@endif
<form method="POST" action="{{url('admin/createadmin')}}">
    {!! csrf_field() !!}

    <div class='form-group'>
        <label for="name">Nombre:</label>
        <input type="text" name="name" class="form-control" value="{{ old('name') }}" />
        <div class="text-danger">{{$errors->first('name')}}</div>
    </div>

    <div class="form-group">
        <label for="email">Email:</label>
        <input type="email" name="email" class="form-control" value="{{ old('email') }}" />
        <div class="text-danger">{{$errors->first('email')}}</div>
    </div>

    <div class="form-group">
        <label for="password">Password:</label>
        <input type="password" class="form-control" name="password">
        <div class="text-danger">{{$errors->first('password')}}</div>
    </div>

    <div class="form-group">
        <label for="password_confirmation">Confirmar Password:</label>
        <input type="password" class="form-control" name="password_confirmation">
    </div>

    <div>
        <button type="submit" class="btn btn-primary">Crear administrador</button>
    </div>
</form>
<br /><br /><br /><br />
@stop


Como podéis ver el formulario es prácticamente igual al formulario de registro que ya creamos en un capítulo anterior.

Ahora en el navegador, vamos a la nueva ruta "admin/createadmin" para registrar un administrador. Una vez que hemos creado el/los administrador/es es muy importante que comentemos la acción "createAdmin" y la ruta que la conecta.

Ahora incluiremos la lógica al controlador "AdminController", para ello incluiremos el método constructor y haremos uso de middleware para permitir el acceso al mismo sólo a los usuarios autenticados, excepto a la acción createAdmin.

    public function __construct(){
        $this->middleware('auth', ['except' => 'createAdmin']);
    }


A continuación crearemos un método privado que será el encargado de comprobar si el usuario autenticado es administrador o no. Este método luego será utilizado en cada una de las acciones del controlador. Código del método privado isAdmin() ...

    private function isAdmin(){
        if (Auth::user()->user == 1) return true;
        else return false;
    }


El método anterior regresa un valor boolean. Si la columna "user" del usuario autenticado es igual 1 es que es administrador. Para ver la prueba crearemos una nueva acción-ruta llamada "admin" con el siguiente código ...

    public function admin(){
        if ($this->isAdmin()){
            return View('admin.admin');
        } else{
            return redirect()->back();
        }
    }


Si el usuario es administrador mostramos una vista de lo contrario lo expulsamos redireccionándolo de dónde vino.

Esta acción "admin" la conectaremos a una nueva ruta en routes.php ...

Route::get('admin', 'AdminController@admin');


Y crearemos la nueva vista "admin.blade.php" en la carpeta "admin" con el siguiente código ...

@extends('layouts.home')
@section('content')
<h1>Bienvenid@ {{Auth::user()->name}} a su Panel de Administrador</h1>
@stop


Otra cosa que podemos hacer para finalizar es agregar un link al ménu del layout "home.blade.php" que permita al usuario administrador, ir al panel de administrador ...

          <ul class="nav navbar-nav navbar-right">
   @if (Auth::check())
                        @if (Auth::user()->user == 1)
   <li><a href="{{url('admin')}}">Panel de Administrador</a></li>
                        @endif
   <li><a href="{{url('user')}}">{{Auth::user()->name}}</a></li>
   <li><a href="{{url('auth/logout')}}">Salir</a></li>
   @else
            <li><a href="{{url('auth/login')}}">Iniciar sesión</a></li>
   @endif
          </ul>


Ahora prueben a iniciar sesión como usuarios normales y como administradores.