1. 2 Create Database Menu (ok)

Project Practice First

Bước 1: Tạo dữ liệu bảng menu_role để test chức năng

C:\xampp82\htdocs\testvn\database\seeders\MenusTableSeeder.php

<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class MenusTableSeeder extends Seeder
{
  private $joinData = array();
  public function join($roles, $menuId)
  {
    $roles = explode(",", $roles);
    foreach ($roles as $role) {
      array_push($this->joinData, ["role_name" => $role, "menus_id" => $menuId]);
    }
  }
  public function joinAllByTransaction()
  {
    foreach ($this->joinData as $data) {
      DB::table('menu_role')->insert([
        "role_name" => $data['role_name'],
        "menus_id" => $data['menus_id']
      ]);
    }
  }
  /**
   * Run the database seeds.
   */
  public function run(): void
  {
    $this->join("admin,user,test",1);
    $this->joinAllByTransaction();
  }
}

Bước 2: Tạo dữ liệu bảng permissionsrole_has_permissions

C:\xampp82\htdocs\testvn\database\seeders\MenusTableSeeder.php

<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
class MenusTableSeeder extends Seeder
{
  private $joinData = array();
  private $sequence = 1;
  private $dropdown = false;
  private $useRole = null;
  private $useAdmin = null;
  public function join($roles, $menuId)
  {
    $roles = explode(",", $roles);
    foreach ($roles as $role) {
      array_push($this->joinData, ["role_name" => $role, "menus_id" => $menuId]);
    }
  }
  public function joinAllByTransaction()
  {
    foreach ($this->joinData as $data) {
      DB::table('menu_role')->insert([
        "role_name" => $data['role_name'],
        "menus_id" => $data['menus_id']
      ]);
    }
  }
  public function insertLink($roles, $name, $href, $icon = null)
  {
    if ($this->dropdown == false) {
      DB::table('menus')->insert([
        "name" => $name,
        "href" => $href,
        "icon" => $icon,
        "slug" => "test",
        "parent_id" => null,
        "menu_id" => 1,
        "sequence" => $this->sequence
      ]);
    } else {
      DB::table('menus')->insert([
        "name" => $name,
        "href" => $href,
        "icon" => $icon,
        "slug" => "test",
        "parent_id" => null,
        "menu_id" => 1,
        "sequence" => $this->sequence
      ]);
    }
    $lastId = DB::getPdo()->lastInsertId();
    $this->sequence++;
    $this->join($roles, $lastId);
    $permission = Permission::where('name', $name)->get();
    if (!count($permission)) {
      $permission = Permission::create(['name' => "view " . $name]);
    }
    $roles = explode(',', $roles);
    if(in_array('user',$roles)) {
      $this->useRole->givePermissionTo($permission);
    }
    if(in_array('admin',$roles)) {
      $this->useAdmin->givePermissionTo($permission);
    }
    return $lastId;
  }
  /**
   * Run the database seeds.
   */
  public function run(): void
  {
    $this->useRole = Role::where('name','user')->first();
    $this->useAdmin = Role::where('name','admin')->first();
    $this->insertLink("user,admin,test","Test","/test","fa");
  }
}

Bước 3: Tạo dữ liệu bảng menulistmenus

C:\xampp82\htdocs\testvn\database\seeders\MenusTableSeeder.php

<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
class MenusTableSeeder extends Seeder
{
  private $joinData = array();
  private $sequence = 1;
  private $dropdown = false;
  private $useRole = null;
  private $useAdmin = null;
  private $menuId = null;
  public function join($roles, $menuId)
  {
    $roles = explode(",", $roles);
    foreach ($roles as $role) {
      array_push($this->joinData, ["role_name" => $role, "menus_id" => $menuId]);
    }
  }
  public function joinAllByTransaction()
  {
    foreach ($this->joinData as $data) {
      DB::table('menu_role')->insert([
        "role_name" => $data['role_name'],
        "menus_id" => $data['menus_id']
      ]);
    }
  }
  public function insertLink($roles, $name, $href, $icon = null)
  {
    if ($this->dropdown == false) {
      DB::table('menus')->insert([
        "name" => $name,
        "href" => $href,
        "icon" => $icon,
        "slug" => "test",
        "parent_id" => null,
        "menu_id" => 1,
        "sequence" => $this->sequence
      ]);
    } else {
      DB::table('menus')->insert([
        "name" => $name,
        "href" => $href,
        "icon" => $icon,
        "slug" => "test",
        "parent_id" => null,
        "menu_id" => $this->menuId,
        "sequence" => $this->sequence
      ]);
    }
    $lastId = DB::getPdo()->lastInsertId();
    $this->sequence++;
    $this->join($roles, $lastId);
    $permission = Permission::where('name', $name)->get();
    if (!count($permission)) {
      $permission = Permission::create(['name' => "view " . $name]);
    }
    $roles = explode(',', $roles);
    if (in_array('user', $roles)) {
      $this->useRole->givePermissionTo($permission);
    }
    if (in_array('admin', $roles)) {
      $this->useAdmin->givePermissionTo($permission);
    }
    return $lastId;
  }
  public function insertTitle($roles, $name)
  {
    DB::table('menus')->insert([
      "name" => $name,
      "href" => null,
      "icon" => null,
      "slug" => "tile",
      "parent_id" => null,
      "menu_id" => $this->menuId,
      "sequence" => $this->sequence
    ]);
    $this->sequence++;
    $lastId = DB::getPdo()->lastInsertId();
    return $lastId;
  }
  /**
   * Run the database seeds.
   */
  public function run(): void
  {
    $this->useRole = Role::where('name', 'user')->first();
    $this->useAdmin = Role::where('name', 'admin')->first();
    DB::table("menulist")->insert(['name' => 'top menu']);
    $this->menuId = DB::getPdo()->lastInsertId();
    $this->insertLink("user,admin,test", "Test", "/test", "fa");
    $this->insertTitle("admin,test", "Product");
  }
}

Bước 4: Tạo dữ liệu dropdown cho menus, menu_role

C:\xampp82\htdocs\testvn\database\seeders\MenusTableSeeder.php

<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
class MenusTableSeeder extends Seeder
{
  private $joinData = [];
  private $sequence = 1;
  private $dropdown = false;
  private $useRole = null;
  private $useAdmin = null;
  private $menuId = null;
  private $dropdownId = [];
  public function join($roles, $menuId)
  {
    $roles = explode(",", $roles);
    foreach ($roles as $role) {
      array_push($this->joinData, ["role_name" => $role, "menus_id" => $menuId]);
    }
  }
  public function joinAllByTransaction()
  {
    foreach ($this->joinData as $data) {
      DB::table('menu_role')->insert([
        "role_name" => $data['role_name'],
        "menus_id" => $data['menus_id']
      ]);
    }
  }
  public function insertLink($roles, $name, $href, $icon = null)
  {
    if ($this->dropdown == false) {
      DB::table('menus')->insert([
        "name" => $name,
        "href" => $href,
        "icon" => $icon,
        "slug" => "test",
        "parent_id" => null,
        "menu_id" => 1,
        "sequence" => $this->sequence
      ]);
    } else {
      DB::table('menus')->insert([
        "name" => $name,
        "href" => $href,
        "icon" => $icon,
        "slug" => "link",
        "parent_id" => null,
        "menu_id" => $this->menuId,
        "sequence" => $this->sequence
      ]);
    }
    $lastId = DB::getPdo()->lastInsertId();
    $this->sequence++;
    $this->join($roles, $lastId);
    $permission = Permission::where('name', $name)->get();
    if (!count($permission)) {
      $permission = Permission::create(['name' => "view " . $name]);
    }
    $roles = explode(',', $roles);
    if (in_array('user', $roles)) {
      $this->useRole->givePermissionTo($permission);
    }
    if (in_array('admin', $roles)) {
      $this->useAdmin->givePermissionTo($permission);
    }
    return $lastId;
  }
  public function insertTitle($roles, $name)
  {
    DB::table('menus')->insert([
      "name" => $name,
      "href" => null,
      "icon" => null,
      "slug" => "tile",
      "parent_id" => null,
      "menu_id" => $this->menuId,
      "sequence" => $this->sequence
    ]);
    $this->sequence++;
    $lastId = DB::getPdo()->lastInsertId();
    return $lastId;
  }
  public function beginDropdown($roles, $name, $icon = null)
  {
    $parentId = null;
    DB::table('menus')->insert([
      "name" => $name,
      "href" => null,
      "icon" => null,
      "slug" => "dropdown",
      "parent_id" => $parentId,
      "menu_id" => $this->menuId,
      "sequence" => $this->sequence
    ]);
    $this->sequence++;
    $lastId = DB::getPdo()->lastInsertId();
    array_push($this->dropdownId, $lastId);
    $this->dropdown = true;
    $this->join($roles, $lastId);
    return $lastId;
  }
  public function endDropdown() {
    $this->dropdown = false;
    array_pop( $this->dropdownId );
  }
  /**
   * Run the database seeds.
   */
  public function run(): void
  {
    $this->useRole = Role::where('name', 'user')->first();
    $this->useAdmin = Role::where('name', 'admin')->first();
    DB::table("menulist")->insert(['name' => 'top menu']);
    $this->menuId = DB::getPdo()->lastInsertId();
    $this->insertLink("user,admin,test", "Test", "/test", "fa");
    $this->insertTitle("admin,test", "Product");
    $this->beginDropdown("user,admin,test", "SEO", "fas");
      $this->insertLink("user,admin,test", "Test 2", "/test2", "fa");
    $this->endDropdown();
    $this->joinAllByTransaction();
  }
}

Bước 5: Hoàn thiện

C:\xampp82\htdocs\testnet\database\seeders\MenusTableSeeder.php

<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class MenusTableSeeder extends Seeder
{
  private $joinData = [];
  private $dropdown = false;
  private $menuId = null;
  private $dropdownId = [];
  private $sequence = 1;
  public function join($roles, $menuId)
  {
    $roles = explode(',', $roles);
    foreach ($roles as $role) {
      array_push($this->joinData, ['role_name' => $role, 'menus_id' => $menuId]);
    }
  }
  public function joinAllData()
  {
    foreach ($this->joinData as $data) {
      DB::table('menu_role')->insert($data);
    }
  }
  public function insertLink($roles, $name, $slug,$icon = null)
  {
    if ($this->dropdown == false) {
      DB::table('menus')->insert([
        'name' => $name,
        'icon' => $icon,
        'slug' => $slug,
        'target' => 'link',
        'menu_id' => $this->menuId,
        'parent_id' => null,
        'sequence' => $this->sequence
      ]);
    } else {
      DB::table('menus')->insert([
        'name' => $name,
        'icon' => $icon,
        'slug' => $slug,
        'target' => 'link',
        'menu_id' => $this->menuId,
        'parent_id' => $this->dropdownId[count($this->dropdownId) - 1],
        'sequence' => $this->sequence
      ]);
    }
    $this->sequence++;
    $lastId = DB::getPdo()->lastInsertId();
    $this->join($roles, $lastId);
    return $lastId;
  }
  public function insertTitle($roles, $name)
  {
    DB::table('menus')->insert([
      'name' => $name,
      'icon' => null,
      'slug' => null,
      'target' => 'text',
      'menu_id' => null,
      'parent_id' => null,
      'sequence' => $this->sequence
    ]);
    $this->sequence++;
    $lastId = DB::getPdo()->lastInsertId();
    $this->join($roles, $lastId);
    return $lastId;
  }
  public function beginDropdown($roles, $name,$icon = null)
  {
    if (count($this->dropdownId)) {
      $parentId = $this->dropdownId[count($this->dropdownId) - 1];
    } else {
      $parentId = null;
    }
    DB::table('menus')->insert([
      'name' => $name,
      'icon' => $icon,
      'slug' => null,
      'target' => 'dropdown',
      'menu_id' => $this->menuId,
      'parent_id' => $parentId,
      'sequence' => $this->sequence
    ]);
    $this->sequence++;
    $lastId = DB::getPdo()->lastInsertId();
    array_push($this->dropdownId, $lastId);
    $this->dropdown = true;
    $this->join($roles, $lastId);
    return $lastId;
  }
  public function endDropdown()
  {
    $this->dropdown = false;
    array_pop($this->dropdownId);
  }
  /**
   * Run the database seeds.
   */
  public function run(): void
  {
    DB::table('menulist')->insert([
      'name' => 'sidebar menu'
    ]);
    $this->menuId = DB::getPdo()->lastInsertId();  //set menuId
    $this->insertLink('guest,user,admin', 'Dashboard', '/', 'cil-speedometer');
    $this->beginDropdown('admin', 'Settings', 'cil-calculator');
    $this->insertLink('admin', 'Notes',                   '/notes');
    $this->insertLink('admin', 'Users',                   '/users');
    $this->insertLink('admin', 'Edit menu',               '/menu/menu');
    $this->insertLink('admin', 'Edit menu elements',      '/menu/element');
    $this->insertLink('admin', 'Edit roles',              '/roles');
    $this->insertLink('admin', 'Media',                   '/media');
    $this->insertLink('admin', 'BREAD',                   '/bread');
    $this->insertLink('admin', 'Email',                   '/mail');
    $this->endDropdown();
    $this->insertLink('guest', 'Login', '/login', 'cil-account-logout');
    $this->insertLink('guest', 'Register', '/register', 'cil-account-logout');
    $this->insertTitle('user,admin', 'Theme');
    $this->insertLink('user,admin', 'Colors', '/colors', 'cil-drop1');
    $this->insertLink('user,admin', 'Typography', '/typography', 'cil-pencil');
    $this->beginDropdown('user,admin', 'Base', 'cil-puzzle');
    $this->insertLink('user,admin', 'Breadcrumb',    '/base/breadcrumb');
    $this->insertLink('user,admin', 'Cards',         '/base/cards');
    $this->insertLink('user,admin', 'Carousel',      '/base/carousel');
    $this->insertLink('user,admin', 'Collapse',      '/base/collapse');
    $this->insertLink('user,admin', 'Forms',         '/base/forms');
    $this->insertLink('user,admin', 'Jumbotron',     '/base/jumbotron');
    $this->insertLink('user,admin', 'List group',    '/base/list-group');
    $this->insertLink('user,admin', 'Navs',          '/base/navs');
    $this->insertLink('user,admin', 'Pagination',    '/base/pagination');
    $this->insertLink('user,admin', 'Popovers',      '/base/popovers');
    $this->insertLink('user,admin', 'Progress',      '/base/progress');
    $this->insertLink('user,admin', 'Scrollspy',     '/base/scrollspy');
    $this->insertLink('user,admin', 'Switches',      '/base/switches');
    $this->insertLink('user,admin', 'Tables',        '/base/tables');
    $this->insertLink('user,admin', 'Tabs',          '/base/tabs');
    $this->insertLink('user,admin', 'Tooltips',      '/base/tooltips');
    $this->endDropdown();
    $this->beginDropdown('user,admin', 'Buttons', 'cil-cursor');
    $this->insertLink('user,admin', 'Buttons',           '/buttons/buttons');
    $this->insertLink('user,admin', 'Buttons Group',     '/buttons/button-group');
    $this->insertLink('user,admin', 'Dropdowns',         '/buttons/dropdowns');
    $this->insertLink('user,admin', 'Brand Buttons',     '/buttons/brand-buttons');
    $this->endDropdown();
    $this->insertLink('user,admin', 'Charts', '/charts', 'cil-chart-pie');
    $this->beginDropdown('user,admin', 'Icons', 'cil-star');
    $this->insertLink('user,admin', 'CoreUI Icons',      '/icon/coreui-icons');
    $this->insertLink('user,admin', 'Flags',             '/icon/flags');
    $this->insertLink('user,admin', 'Brands',            '/icon/brands');
    $this->endDropdown();
    $this->beginDropdown('user,admin', 'Notifications', 'cil-bell');
    $this->insertLink('user,admin', 'Alerts',     '/notifications/alerts');
    $this->insertLink('user,admin', 'Badge',      '/notifications/badge');
    $this->insertLink('user,admin', 'Modals',     '/notifications/modals');
    $this->endDropdown();
    $this->insertLink('user,admin', 'Widgets', '/widgets', 'cil-calculator');
    $this->insertTitle('user,admin', 'Extras');
    $this->beginDropdown('user,admin', 'Pages', 'cil-star');
    $this->insertLink('user,admin', 'Login',         '/login');
    $this->insertLink('user,admin', 'Register',      '/register');
    $this->insertLink('user,admin', 'Error 404',     '/404');
    $this->insertLink('user,admin', 'Error 500',     '/500');
    $this->endDropdown();
    $this->insertLink('guest,user,admin', 'Download CoreUI', 'https://coreui.io', 'cil-cloud-download');
    $this->insertLink('guest,user,admin', 'Try CoreUI PRO', 'https://coreui.io/pro/', 'cil-layers');
    /* Create top menu */
    DB::table('menulist')->insert([
      'name' => 'top menu'
    ]);
    $this->menuId = DB::getPdo()->lastInsertId();  //set menuId
    $this->beginDropdown('guest,user,admin', 'Pages');
    $id = $this->insertLink('guest,user,admin', 'Dashboard',    '/');
    $id = $this->insertLink('user,admin', 'Notes',              '/notes');
    $id = $this->insertLink('admin', 'Users',                   '/users');
    $this->endDropdown();
    $id = $this->beginDropdown('admin', 'Settings');
    $id = $this->insertLink('admin', 'Edit menu',               '/menu/menu');
    $id = $this->insertLink('admin', 'Edit menu elements',      '/menu/element');
    $id = $this->insertLink('admin', 'Edit roles',              '/roles');
    $id = $this->insertLink('admin', 'Media',                   '/media');
    $id = $this->insertLink('admin', 'BREAD',                   '/bread');
    $this->endDropdown();
    $this->joinAllData();
  }
}

C:\xampp82\htdocs\testnet\database\migrations\2023_05_03_170949_create_menulist_table.php

<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
  /**
   * Run the migrations.
   */
  public function up(): void
  {
    Schema::create('menulist', function (Blueprint $table) {
      $table->id();
      $table->string('name');
      $table->timestamps();
    });
  }
  /**
   * Reverse the migrations.
   */
  public function down(): void
  {
    Schema::dropIfExists('menulist');
  }
};

C:\xampp82\htdocs\testnet\database\migrations\2023_05_03_170952_create_menus_table.php

<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
  /**
   * Run the migrations.
   */
  public function up(): void
  {
    Schema::create('menus', function (Blueprint $table) {
      $table->id();
      $table->string('name');
      $table->string('href')->nullable();
      $table->string('slug');
      $table->string('icon')->nullable();
      $table->integer('parent_id')->unsigned()->nullable();
      $table->integer('menu_id')->unsigned();
      $table->integer('sequence');
      $table->timestamps();
    });
  }
  /**
   * Reverse the migrations.
   */
  public function down(): void
  {
    Schema::dropIfExists('menus');
  }
};

C:\xampp82\htdocs\testnet\database\migrations\2023_05_03_171007_create_menu_role_table.php

<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
  /**
   * Run the migrations.
   */
  public function up(): void
  {
    Schema::create('menu_role', function (Blueprint $table) {
      $table->id();
      $table->string('role_name');
      $table->integer('menus_id')->unsigned();
      $table->timestamps();
    });
  }
  /**
   * Reverse the migrations.
   */
  public function down(): void
  {
    Schema::dropIfExists('menu_role');
  }
};

Last updated