Laravel con Datatables Editor

Requisitos:

  1. Laravel 5.6
  2. Laravel DataTables

Instalamos Laravel en el folder en donde estamos

composer create-project --prefer-dist laravel/laravel . "5.6.*"

Instalamos Laravel Datatables – Editor

composer require yajra/laravel-datatables-oracle:"~8.0"
//v1.6
composer require yajra/laravel-datatables-editor

Usar DataTables Editor

//crear contorlador de usuarios
php artisan make:controller UsersController

//crear clase DataTable para usuarios
php artisan datatables:make Users

//crear clase DataTable Editor para usuarios
php artisan datatables:editor Users

Configuramos la ruta

Route::resource('users', 'UsersController');

Editamos nuestro controlador de usuario

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\DataTables\UsersDataTable;
use App\DataTables\UsersDataTablesEditor;

class UsersController extends Controller
{
    public function index(UsersDataTable $dataTable)
    {
        return $dataTable->render('users.index');
    }

    public function store(UsersDataTablesEditor $editor)
    {
        return $editor->process(request());
    }
}

Editamos nuestra clase DataTable para usuarios

<?php

namespace App\DataTables;

use App\User;
use Yajra\DataTables\Services\DataTable;

class UsersDataTable extends DataTable
{
    /**
     * Build DataTable class.
     *
     * @param mixed $query Results from query() method.
     * @return \Yajra\DataTables\DataTableAbstract
     */
    public function dataTable($query)
    {
        return datatables($query)->setRowId('id')->addColumn('password', '');
    }

    /**
     * Get query source of dataTable.
     *
     * @param \App\User $model
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function query(User $model)
    {
        return $model->newQuery()->select('id', 'name', 'email');
    }

    /**
     * Optional method if you want to use html builder.
     *
     * @return \Yajra\DataTables\Html\Builder
     */
    public function html()
    {
        return $this->builder()
                    ->columns($this->getColumns())
                    ->minifiedAjax()
                    ->parameters([
                        'dom' => 'Bfrtip',
                        'order' => [1, 'asc'],
                        'select' => [
                            'style' => 'os',
                            'selector' => 'td:first-child',
                        ],
                        'buttons' => [
                            ['extend' => 'create', 'editor' => 'editor'],
                            ['extend' => 'edit', 'editor' => 'editor'],
                            ['extend' => 'remove', 'editor' => 'editor'],
                        ]
                    ]);
    }

    /**
     * Get columns.
     *
     * @return array
     */
    protected function getColumns()
    {
        return [
            [
                'data' => null,
                'defaultContent' => '',
                'className' => 'select-checkbox',
                'title' => '',
                'orderable' => false,
                'searchable' => false
            ],
            'id',
            'name',
            'email',
        ];
    }

    /**
     * Get filename for export.
     *
     * @return string
     */
    protected function filename()
    {
        return 'users_' . time();
    }
}

Editamos nuestra clase DataTable Editor para usuarios

<?php

namespace App\DataTables;

use App\User;
use Illuminate\Validation\Rule;
use Yajra\DataTables\DataTablesEditor;
use Illuminate\Database\Eloquent\Model;

class UsersDataTablesEditor extends DataTablesEditor
{
    protected $model = User::class;

    /**
     * Get create action validation rules.
     *
     * @return array
     */
    public function createRules()
    {
        return [
            'email' => 'required|email|unique:users',
            'name'  => 'required',
        ];
    }

    /**
     * Get edit action validation rules.
     *
     * @param Model $model
     * @return array
     */
    public function editRules(Model $model)
    {
        return [
            'email' => 'sometimes|required|email|' . Rule::unique($model->getTable())->ignore($model->getKey()),
            'name'  => 'sometimes|required',
        ];
    }

    /**
     * Get remove action validation rules.
     *
     * @param Model $model
     * @return array
     */
    public function removeRules(Model $model)
    {
        return [];
    }

    /**
    * Pre-create action event hook.
    *
    * @param Model $model
    * @return array
    */
    public function creating(Model $model, array $data)
    {
        $data['password'] = bcrypt($data['password']);

        return $data;
    }

    /**
    * Pre-update action event hook.
    *
    * @param Model $model
    * @return array
    */
    public function updating(Model $model, array $data)
    {
        if (empty($data['password'])) {
            unset($data['password']);
        } else {
            $data['password'] = bcrypt($data['password']);
        }

        return $data;
    }
}

Agregamos la vista de Usuarios

<!doctype html>
<html lang="{{ app()->getLocale() }}">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Laravel DataTables Editor</title>

        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
        <link rel="stylesheet" href="https://cdn.datatables.net/1.10.16/css/dataTables.bootstrap.min.css">
        <link rel="stylesheet" href="https://cdn.datatables.net/buttons/1.5.0/css/buttons.bootstrap.min.css">
        <link rel="stylesheet" href="https://cdn.datatables.net/select/1.2.4/css/select.bootstrap.min.css">
        <link rel="stylesheet" href="/plugins/editor/css/dataTables.editor.css">
        <link rel="stylesheet" href="/plugins/editor/css/editor.bootstrap.css">

        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
        <script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
        <script src="https://cdn.datatables.net/buttons/1.5.0/js/dataTables.buttons.min.js"></script>
        <script src="https://cdn.datatables.net/select/1.2.4/js/dataTables.select.min.js"></script>
        <script src="{{asset('plugins/editor/js/dataTables.editor.js')}}"></script>

        <script src="https://cdn.datatables.net/1.10.16/js/dataTables.bootstrap.min.js"></script>
        <script src="https://cdn.datatables.net/buttons/1.5.0/js/buttons.bootstrap.min.js"></script>

        <script src="{{asset('plugins/editor/js/editor.bootstrap.min.js')}}"></script>
    </head>
    <body>
        <div class="container">
            {{$dataTable->table(['id' => 'users'])}}
        </div>

        <script>
            $(function() {
                $.ajaxSetup({
                    headers: {
                        'X-CSRF-TOKEN': '{{csrf_token()}}'
                    }
                });

                var editor = new $.fn.dataTable.Editor({
                    ajax: "/users",
                    table: "#users",
                    display: "bootstrap",
                    fields: [
                        {label: "Name:", name: "name"},
                        {label: "Email:", name: "email"},
                        {label: "Password:", name: "password", type: "password"}
                    ]
                });

                $('#users').on('click', 'tbody td:not(:first-child)', function (e) {
                    editor.inline(this);
                });

                {{$dataTable->generateScripts()}}
            })
        </script>
    </body>
</html>

Levantamos nuestro servidor

php artisan serve

Laravel – solución error tokenmismatchexception

En el archivo .env tienes que comentar lo siguiente

#SESSION_DRIVER=file

Ahora debes mandar como nulo lo siguiente

SESSION_DOMAIN=null

Guardas el archivo y limpias el cache de configuraciones, en consola.

artisan config:clear

Laravel crear roles para usuarios

Requisito

php artisan make:auth

Crear el modelo del Role y la migración

php artisan make:model Role -m

Editamos el archivo de migración para role

public function up(){  
  Schema::create('roles', function (Blueprint $table) {    
    $table->increments('id');    
    $table->string('name');    
    $table->string('description');    
    $table->timestamps();  
  });
}
public function down(){  
  Schema::dropIfExists('roles');
}

Crear tabla usuario vs rol

php artisan make:migration crear_tabla_usuario_rol_tabla

Editar el archivo de migración

public function up(){  
Schema::create('role_user', function (Blueprint $table) {    
$table->increments('id');    
$table->integer('role_id')->unsigned();    
$table->integer('user_id')->unsigned();  
});
}

public function down(){  
Schema::dropIfExists('role_user');
}
public function up(){  
  Schema::create('role_user', function (Blueprint $table) 
  {    
    $table->increments('id');    
    $table->integer('role_id')->unsigned();    
    $table->integer('user_id')->unsigned();  
  });
}
public function down(){  
  Schema::dropIfExists('role_user');
}

Agregar en el modelo User.php la función roles

public function roles() {   return $this->belongsToMany(Role::class); }

Agregar en el modelo Role.php la función users

public function users() {   return $this->belongsToMany(User::class); }

Agregar los Seeder para usuarios y roles (cargar datos predeterminados)

php artisan make:seeder RoleTableSeeder php artisan make:seeder UserTableSeeder

En el directorio database/seeds/

Editar el archivo RoleTableSeeder.php

use Illuminate\Database\Seeder;
use App\Role;
use Illuminate\Database\Seeder;

class RoleTableSeeder extends Seeder{    
public function run()    {        
$role_employee = new Role();        
$role_employee->name = 'employee';        
$role_employee->description = 'A Employee User';        
$role_employee->save();        
$role_manager = new Role();        
$role_manager->name = 'manager';        
$role_manager->description = 'A Manager User';        
$role_manager->save();    
}
}

Editar el archivo UserTableSeeder.php

use Illuminate\Database\Seeder;
use App\Role;
use App\User;
use Illuminate\Database\Seeder;

class UserTableSeeder extends Seeder{    
public function run()    {        
$role_employee = Role::where('name', 'employee')->first();        $role_manager = Role::where('name', 'manager')->first();        
$employee = new User();        

$employee->name = 'Employee Name';        
$employee->email = 'employee@example.com';        
$employee->password = bcrypt('secret');        
$employee->save();

$employee->roles()->attach($role_employee);        
$manager = new User();        
$manager->name = 'Manager Name';        
$manager->email = 'manager@example.com';        
$manager->password = bcrypt('secret');        
$manager->save();        
$manager->roles()->attach($role_manager);    
}
}

Editar el archivo DatabaseSeeder.php

public function run() {   $this->call(RoleTableSeeder::class);   $this->call(UserTableSeeder::class); }

Editar el modelo de usuarios User.php

public function authorizeRoles($roles){  
if (is_array($roles)) {      
return $this->hasAnyRole($roles) ||              abort(401, 'This action is unauthorized.');  
}  
return $this->hasRole($roles) ||          abort(401, 'This action is unauthorized.');
}

public function hasAnyRole($roles){  
return null !== $this->roles()->whereIn(‘name’, $roles)->first();
}

public function hasRole($role){  
return null !== $this->roles()->where(‘name’, $role)->first();

}

Registrar usuarios con rol predeterminado “employee” /Http/Controllers/Auth/RegisterController.php

use App\Role;
class RegisterController extends Controller{
protected function create(array $data){    
$user = User::create([
'name'=> $data['name'],
'email'=> $data['email'],
'password' => bcrypt($data['password']),
]);    
$user->roles()->attach(Role::where('name', 'employee')->first());
return $user;
}
}

Ejecutar los archivos Seeder

php artisan migrate:fresh --seed

Un ejemplo de como utilizar en los controladores

class HomeController extends Controller{  
public function __construct()  {    
$this->middleware('auth');  
}  
public function index(Request $request)  {    
$request->user()->authorizeRoles(['employee', 'manager']);    
return view('home');  
}

Añadir al Middleware

Creamos la verificación del rol

php artisan make:middleware CheckRole

Editamos el archivo CheckRole.php

public function handle($request, Closure $next, $role){    
if (! $request->user()->hasRole($role)) {
return redirect('home');
return $next($request);
}

Registramos el Middleware en la ruta app/Http/Kernel.php

'role' => \App\Http\Middleware\CheckRole::class,

Agregamos en las rutas.

Route::put('post/{id}', function ($id) {     //escribir validacones })->middleware('auth', 'role:admin');

¿Cómo validamos multiples usuarios con Middleware?

En las rutas agregamos los usuarios con la separación de “|”

Route::group(['middleware' => ['auth', 'role:employee|manager']], function () {   Route::get('/admin/home', 'AdminController@index')->name('home'); }); 

Modificaremos el Middleware CheckRole.php

<?php
namespace App\Http\Middleware;
use Closure;
use Auth;
class CheckRole{       
public function handle($request, Closure $next, $roles){                
if ( !Auth::user()->hasRoles($roles) ) {            
return redirect('/404');        
}        
return $next($request);    
}
}

Editar el modelo User.php

public function hasRoles($roles){
$roles_array = explode("|", $roles);
if ($this->roles()->whereIn('name', $roles_array)->first()) {
return true;
}
return false;
}

Laravel 5.6, corregir valor null cuando los campos de un formulario están vacíos

en el archivo app/Http/Kernel.php comentar la siguiente linea

 
protected $middleware = [
        \App\Http\Middleware\CheckForMaintenanceMode::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        //\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
        \App\Http\Middleware\TrustProxies::class,
    ];

en el archivo config/database.php, esto nos permitira guardar solo parte de los datos en la base de datos, sin tener que llenar todos completos.

'mysql' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            /*'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',*/
            'charset' => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix' => '',
            'strict' => false,//cambiar aqui por false
            'engine' => null,
        ],

Laravel Cors – permitir que otros servidores reciban información de nuestro app

Para quitar el error de Access-Control-Allow-Origin, ejecutaremos los siguientes comandos.

php artisan make:middleware Cors

Configuraremos de la siguiente manera el nuevo archivo creado con el comando anterior /app/Http/Middleware/Cors.php

<?php

namespace App\Http\Middleware;

use Closure;

class Cors
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        //return $next($request);
        return $next($request)
        ->header('Access-Control-Allow-Origin', '*')
        ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
    }
}

Ahora para que Laravel reconozca nuestro middleware personalizado agregaremos el siguiente configuración en el archivo /app/Http/Kernel.php

protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'can' => \Illuminate\Foundation\Http\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'cors' => \App\Http\Middleware\Cors::class, //esta es la configuración
    ];

Agregamos la excepción enapp/Http/Middleware/VerifyCsrfToken.php

protected $except = [
    '/api/*'
];

Ya puedes usar el middlware como siempre en el archivo /app/Http/routes.php

Route::group(['middleware' => 'cors', 'prefix' => 'api'], function()
{
  //podemos seguir recibiendo los metodos
});

Instalar Laravel 5.2

Instalamos Laravel 5.2, nombre_de_tu_proyecto será la carpeta en donde se instalará Laravel.

composer create-project laravel/laravel nombre_de_tu_poyecto 5.2.*

Agregamos el modulo de login

php artisan make:auth

Levantamos el servidor en el  url http://localhost:8000/

php artisan serve

Configuramos las credenciales de la base de datos en el archivo .env

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=nombre_base_de_datos
DB_USERNAME=nombre_de_usuario
DB_PASSWORD=contraseña

Ejecutamos la migración para generar las tablas en la base de datos que necesita el login

php artisan migrate