Laravel 8

Créer un blog – les utilisateurs

Nous avons dans le précédent article codé tout ce qui concerne les catégories. On en a profité pour élaborer un contrôleur de ressource universel qui devrait encore nous faire économiser du code. Maintenant on va traiter les utilisateurs. Cette fonctionnalité ne sera accessible que pour l’administrateur. Il doit avoir un tableau avec les principales informations : nom, email, rôle… Il doit aussi pouvoir apporter des modifications, en particulier changer le rôle ou valider l’utilisateur pour les commentaires. Et il doit aussi pouvoir faire une suppression.

Vous pouvez télécharger le code final de cet article ici.

La validation

Il faut créer la form request pour la validation :

php artisan make:request Back\UserRequest

<?php

namespace App\Http\Requests\Back;

use Illuminate\Foundation\Http\FormRequest;

class UserRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        $id = basename($this->url());

        return $rules = [
            'name' => 'required|max:255|unique:users,name,' . $id,
            'email' => 'required|email|max:255|unique:users,email,' . $id
        ];
    }
}

Le tableau

On crée la Datatable :

php artisan datatables:make Users

<?php

namespace App\DataTables;

use App\Models\User;
use Yajra\DataTables\Html\Column;
use Yajra\DataTables\Services\DataTable;
use Illuminate\Support\Facades\Route;

class UsersDataTable extends DataTable
{
    use DataTableTrait;

    public function dataTable($query)
    {
        return datatables()
            ->eloquent($query)
            ->editColumn('valid', function ($user) {
                return $user->valid ? '<i class="fas fa-check"></i>' : '';
            })
            ->editColumn('created_at', function ($user) {
                return formatDate($user->created_at);
            })
            ->editColumn('updated_at', function ($user) {
                return formatDate($user->updated_at);
            })
            ->addColumn('action', function ($user) {
                return $this->button(
                          'users.edit', 
                          $user->id, 
                          'warning', 
                          __('Edit'), 
                          'edit'
                      ). $this->button(
                          'users.destroy', 
                          $user->id, 
                          'danger', 
                          __('Delete'), 
                          'trash-alt', 
                          __('Really delete this user?')
                      );
            })
            ->rawColumns(['valid', 'action']);
    }

    public function query(User $model)
    {
        if(Route::currentRouteNamed('users.indexnew')) {
            return $model->has('unreadNotifications');
        }

        return $model->newQuery();
    }

    public function html()
    {
        return $this->builder()
                    ->setTableId('users-table')
                    ->columns($this->getColumns())
                    ->minifiedAjax()
                    ->dom('Blfrtip')
                    ->lengthMenu();
    }

    protected function getColumns()
    {
        return [
            Column::make('name')->title(__('Name')),
            Column::make('email')->title(__('Email')),
            Column::make('role')->title(__('Role')),
            Column::make('created_at')->title('Creation'),
            Column::make('updated_at')->title('Modification'),
            Column::make('valid')->title(__('Valid'))->addClass('align-middle text-center'),            
            Column::computed('action')->title(__('Action'))->addClass('align-middle text-center'),
        ];
    }

    protected function filename()
    {
        return 'Users_' . date('YmdHis');
    }
}

Le contrôleur

On a créé un contrôleur de ressource mais évidemment on tombe forcément sur des cas particuliers et c’est le cas avec les utilisateurs. Pour la mise à jour d’un utilisateur on va avoir une case à cocher pour la validation des commentaires. On peut difficilement généraliser la chose alors on crée un contrôleur qui va étendre le contrôleur de ressource :

php artisan make:controller Back\UserController --model=User

Dans ce contrôleur on étend la ressource et on surcharge la méthode update :

<?php

namespace App\Http\Controllers\Back;

use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\Request;
use App\Http\Requests\Back\UserRequest;

class UserController extends ResourceController
{
    public function update($id)
    {
        $request = app()->make(UserRequest::class);

        $request->merge([
            'valid' => $request->has('valid'),
        ]);

        User::findOrFail($id)->update($request->all());

        return back()->with('ok', __('The user has been successfully updated'));
    }
}

Les routes

Pour les routes c’est simple, on a une ressource et on va se passer de show, create et store. D’autre part on a besoin d’une route supplémentaire pour les nouveaux commentaires :

use App\Http\Controllers\Back\{
    AdminController,
    PostController as BackPostController,
    UserController as BackUserController,
    ResourceController as BackResourceController
};

...

Route::prefix('admin')->group(function () {

    ...

    Route::middleware('admin')->group(function () {
        
        ...

        // Users
        Route::resource('users', BackUserController::class)->except(['show', 'create', 'store']);
        Route::name('users.indexnew')->get('newusers', [BackResourceController::class, 'index']);
    });

La configuration

Les titres

Dans app/config/titles on ajoute les titres pour les utilisateurs :

'users' => [
    'index'    => 'Users',
    'edit'     => 'User Edit',
    'indexnew' => 'New Users',
],

Le menu

Dans app/config/menu on ajoute les items pour les utilisateurs :

'Users' => [
    'icon' => 'user',
    'role'   => 'admin',
    'children' => [
        [
            'name'  => 'All users',
            'role'  => 'admin',
            'route' => 'users.index',
        ],
        [
            'name'  => 'New users',
            'role'  => 'admin',
            'route' => 'users.indexnew',
        ],
        [
            'name'  => 'fake',
            'role'  => 'admin',
            'route' => 'users.edit',
        ],
    ],
],

On doit avoir du nouveau dans le menu :

L’aspect

On a tout en place pour afficher le tableau dans l’administration :

Je rappelle que valide concerne le fait que les commentaires ont été validés (ou pas) pour cet utilisateur.

Le bouton de suppression fonctionne puisqu’on avait prévu du code générique. Par contre on doit s’occuper maintenant de la modification.

Ca doit aussi fonctionner pour les nouveaux utilisateurs :

Modifier un utilisateur

On crée la vue :

Là on profite encore de nos composants :

@extends('back.layout')

@section('main')

    <form 
        method="post" 
        action="{{ route('users.update', $user->id) }}">
        @method('PUT')
        @csrf

        <div class="row">
          <div class="col-md-12">
                
                <x-back.validation-errors :errors="$errors" />

                @if(session('ok'))
                    <x-back.alert 
                        type='success'
                        title="{!! session('ok') !!}">
                    </x-back.alert>
                @endif

                <x-back.card
                    type='info'
                    :outline="true"
                    title=''>
                    <x-back.input
                        title='Name'
                        name='name'
                        :value='$user->name'
                        input='text'
                        :required="true">
                    </x-back.input>
                    <x-back.input
                        title='Email'
                        name='email'
                        :value='$user->email'
                        input='text'
                        :required="true">
                    </x-back.input>
                    <x-back.input
                        title='Role'
                        name='role'
                        :value='$user->role'
                        :options="['admin','redac','user']"
                        input='select'
                        :required="true">
                    </x-back.input>
                    <x-back.input
                        name='valid'
                        :value='$user->valid'
                        input='checkbox'
                        label="Valid">
                    </x-back.input>
                </x-back.card>

                <button type="submit" class="btn btn-primary">@lang('Submit')</button>

              </div>
        </div>
    </form>

@endsection

On doit obtenir le formulaire en cliquant sur un bouton de modification du tableau :

Vous pouvez vérifier la validation :

Si la modification s’effectue correctement on a une alerte :

Conclusion

On voit que le fait d’avoir prévu du code assez général en amont nous aide maintenant. Il y a évidemment certaines particularités rencontrées mais globalement le codage en est grandement facilité.

 

Print Friendly, PDF & Email

6 commentaires

  • DIM

    Salut Best , j’ai un souci en fait dans mon projet je gère l’ajout d’utilisateur depuis l’administration le souci est que j’ai la table status qui est de type enum c’est à dire une liste déroulante mais quand j’insère un nouvel utilisateur
    c’est juste la première option qui est prise en compte malgré le fait que je choisisse la deuxième option voici de plus amples informations

    status :  » »
    :options= »[‘chomeur’,’travailleur’] »
    input=’select’
    :required= »true »>

    @foreach($options as $option)
    option
    value= »{{ $option }} »
    {{ old($name) ? (old($name) == $option ? ‘selected’ :  ») : ($option == $value ? ‘selected’ :  ») }}>
    {{ $option }}
    </option
    @endforeach
    </select

    j'aimerai avoir à choisir entre les deux options ci dessus. je crois que le problème se trouve au niveau du composant .

    Merci.

    • bensa

      C’est bon le problème est résolu il s’agit d’une erreur qui concerne la fonction formatDate, dans la table UsersDatatable, j’ai utilisé le même principe que la fonction getDate de postsDatatable pour résoudre ce problème

  • oksam

    Bonjour Best j’ai un soucis avec la modification, une erreur dont les explications que j’ai trouvé fait d’un problème de casse, j’ai revu encore et encore le code mais rien tu as une idée:
    Illuminate\Database\QueryException
    SQLSTATE[42S22]: Column not found: 1054 Unknown column ‘name4’ in ‘where clause’ (SQL: select count(*) as aggregate from `users` where `name4` = Orpha Herman)

Laisser un commentaire