😝Package spatie/menu full phần 3 tách ra để nghiên cứu (ok)

Xem phần này để rõ hơn vì có lược bỏ và bớt đi một số phần thừa.

Part 1: Tạo dữ liệu

C:\xampp82\htdocs\lva2\app\Models\Post.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
  use HasFactory;
}

C:\xampp82\htdocs\lva2\app\Models\Role.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Role extends Model
{
  use HasFactory;
  /**
   * The attributes that are mass assignable.
   *
   * @var array
   */
  protected $fillable = ['name'];
  public $timestamps = false;
  /**
   * Find role by it's name.
   *
   * @param  string  $name
   * @return self
   */
  public static function findByName($name)
  {
    return static::where('name', $name)->first();
  }
  /**
   * Find all roles that have given names.
   *
   * @param  array|string  $names
   * @return \Illuminate\Database\Eloquent\Collection
   */
  public static function findAllByName($names)
  {
    return static::whereIn('name', $names)->get();
  }
}

C:\xampp82\htdocs\lva2\app\Models\User.php

<?php

namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use App\Trait\HasRoles;

class User extends Authenticatable
{
  use HasApiTokens, HasFactory, Notifiable, HasRoles;
  /**
   * The attributes that are mass assignable.
   *
   * @var array<int, string>
   */
  protected $fillable = [
    'name',
    'email',
    'password',
  ];
  /**
   * The attributes that should be hidden for serialization.
   *
   * @var array<int, string>
   */
  protected $hidden = [
    'password',
    'remember_token',
  ];
  /**
   * The attributes that should be cast.
   *
   * @var array<string, string>
   */
  protected $casts = [
    'email_verified_at' => 'datetime',
  ];
}

C:\xampp82\htdocs\lva2\app\Trait\HasRoles.php

<?php

namespace App\Trait;

use App\Models\Role;

trait HasRoles
{
  /**
   * Relation to roles that the user has.
   *
   * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
   */
  public function roles()
  {
    return $this->belongsToMany(Role::class);
  }
  /**
   * Get names of roles the user has.
   *
   * @return \Illuminate\Support\Collection
   */
  protected function roleNames()
  {
    return $this->roles->pluck('name');
  }
  /**
   * Check if user has given role.
   *
   * @param  string  $role
   * @return bool
   */
  public function hasRole($role)
  {
    return $this->roleNames()->contains($role);
  }
  /**
   * Check if user has one or more of the given roles.
   *
   * @param  array  $roles
   * @return bool
   */
  public function hasAnyRole(array $roles)
  {
    return $this->roleNames()->intersect($roles)->isNotEmpty();
  }
  /**
   * Check if user has all the given roles.
   *
   * @param  array  $roles
   * @return bool
   */
  public function hasAllRoles(array $roles)
  {
    return count($roles) === $this->roleNames()->intersect($roles)->count();
  }
}

C:\xampp82\htdocs\lva2\database\factories\PostFactory.php

<?php

namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Model>
 */
class PostFactory extends Factory
{
  /**
   * Define the model's default state.
   *
   * @return array<string, mixed>
   */
  public function definition(): array
  {
    $title = $this->faker->text(15);
    $slug = Str::slug($title, '-');
    $content = $this->faker->text(150);
    return [
      'title'    => $title,
      'slug'    => $slug,
      'content' => $content
    ];
  }
}

C:\xampp82\htdocs\lva2\database\factories\UserFactory.php

<?php

namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
 */
class UserFactory extends Factory
{
  /**
   * Define the model's default state.
   *
   * @return array<string, mixed>
   */
  public function definition(): array
  {
    return [
      'name' => fake()->name(),
      'email' => fake()->unique()->safeEmail(),
      'email_verified_at' => now(),
      'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
      'remember_token' => Str::random(10),
    ];
  }
  /**
   * Indicate that the model's email address should be unverified.
   */
  public function unverified(): static
  {
    return $this->state(fn (array $attributes) => [
      'email_verified_at' => null,
    ]);
  }
}

C:\xampp82\htdocs\lva2\database\migrations\2023_10_06_015706_create_posts_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('posts', function (Blueprint $table) {
      $table->id();
      $table->string('title');
      $table->string('slug');
      $table->string('content');
      $table->timestamps();
    });
  }
  /**
   * Reverse the migrations.
   */
  public function down(): void
  {
    Schema::dropIfExists('posts');
  }
};

C:\xampp82\htdocs\lva2\database\migrations\2023_10_06_015842_create_roles_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('roles', function (Blueprint $table) {
      $table->id();
      $table->string('name')->unique();
    });
  }
  /**
   * Reverse the migrations.
   */
  public function down(): void
  {
    Schema::dropIfExists('roles');
  }
};

C:\xampp82\htdocs\lva2\database\migrations\2023_10_06_020036_create_role_user_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('role_user', function (Blueprint $table) {
      $table->unsignedInteger('role_id');
      $table->unsignedInteger('user_id');
      $table->primary(['role_id', 'user_id']);
    });
  }
  /**
   * Reverse the migrations.
   */
  public function down(): void
  {
    Schema::dropIfExists('role_user');
  }
};

C:\xampp82\htdocs\lva2\database\seeders\DatabaseSeeder.php

<?php

namespace Database\Seeders;
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
  /**
   * Seed the application's database.
   */
  public function run(): void
  {
    $this->call([RoleSeeder::class, UserSeeder::class, PostSeeder::class]);
  }
}

C:\xampp82\htdocs\lva2\database\seeders\PostSeeder.php

<?php

namespace Database\Seeders;

use App\Models\Post;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class PostSeeder extends Seeder
{
  /**
   * Run the database seeds.
   */
  public function run(): void
  {
    Post::factory()->count(50)->create();
  }
}

Part 2: Sử dụng menu và sử dụng xác thực

Chú ý việc sử dụng $this->middleware('auth'); rất quan trọng nó yêu cầu người dùng phải đăng nhập trước khi có thể truy cập vào đường dẫn. Sau khi đăng nhập nó sẽ chuyển về đúng đường dẫn ban đâu đã nhập trên đường dẫn.

C:\xampp82\htdocs\lva2\app\Http\Controllers\DashboardController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class DashboardController extends Controller
{
  /**
   * Create a new controller instance.
   *
   * @return void
   */
  public function __construct()
  {
    $this->middleware('auth');
  }
  /**
   * Display a listing of the resource.
   */
  public function index()
  {
    //
  }
  /**
   * Show the form for creating a new resource.
   */
  public function create()
  {
    //
  }
  /**
   * Store a newly created resource in storage.
   */
  public function store(Request $request)
  {
    //
  }
  /**
   * Display the specified resource.
   */
  public function show(string $id)
  {
    //
  }
  /**
   * Show the form for editing the specified resource.
   */
  public function edit(string $id)
  {
    //
  }
  /**
   * Update the specified resource in storage.
   */
  public function update(Request $request, string $id)
  {
    //
  }
  /**
   * Remove the specified resource from storage.
   */
  public function destroy(string $id)
  {
    //
  }
  /**
   * Test
   */
  public function test()
  {
    return view('test');
  }
}
Tạo Prefix Route::prefix('admin') nó sẽ tạo trên đường dẫn giống như này. https://lva2.com/admin 😄 Tạo Route Name Route::name('admin.') nó sẽ đặt tên route một cách khoa học hơn. Nó giốn như này tên route admin.index hoặc admin.test ....

C:\xampp82\htdocs\lva2\routes\web.php

<?php

use App\Http\Controllers\DashboardController;
use App\Http\Controllers\HomeController;
use App\Models\Role;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "web" middleware group. Make something great!
|
*/

Route::get('/', function () {
  return view('welcome');
});
Auth::routes();
Route::get('/home', [HomeController::class, 'index'])->name('home');
Route::prefix('admin')->group(function () {
  Route::name('admin.')->group(function () {
    Route::get('/', [DashboardController::class, 'index'])->name('index');
    Route::get('/test', [DashboardController::class, 'test'])->name('test');
  });
});

C:\xampp82\htdocs\lva2\resources\views\test.blade.php

@extends('layouts.admin')
@section('content')
<center>
  <h1>Page Test</h1>
  <h2>Lorem ipsum dolor sit amet consectetur adipisicing elit.</h2>
  <h3>Lorem ipsum dolor sit amet consectetur adipisicing elit.</h3>
  <h4>Lorem ipsum dolor sit amet consectetur adipisicing elit.</h4>
  <h5>Lorem ipsum dolor sit amet consectetur adipisicing elit.</h5>
  <h6>Lorem ipsum dolor sit amet consectetur adipisicing elit.</h6>
</center>
@endsection

Kết quả thật tuyệt vời:

Source code

2MB
spatiemenu.zip
archive

Last updated