Skip to content

Instantly share code, notes, and snippets.

@YugalXD
Last active October 22, 2024 10:25
Show Gist options
  • Save YugalXD/94ea8352116dbfce93705a16405cf4bd to your computer and use it in GitHub Desktop.
Save YugalXD/94ea8352116dbfce93705a16405cf4bd to your computer and use it in GitHub Desktop.
Topic wise plan and steps

Task wise details steps:

1: Introduction to Laravel and system setup

Objective:

  • Set up a Laravel project locally.
  • Understand the basic MVC (Model-View-Controller) structure.
  • Create a simple route, controller, and view.

Step 1: Install PHP, Composer, and Laravel - Done for all

Step 2: Create a New Laravel Project - Done for all

Step 3: Understand Laravel Directory Structure

Top-Level Structure

├── app
├── bootstrap
├── config
├── database
├── public
├── resources
├── routes
├── storage
├── tests
├── vendor
├── .env
├── artisan
├── composer.json
├── package.json
├── phpunit.xml
└── README.md

Let’s break down the purpose of each folder and file:


1. app/ Folder

This is where the core logic of your application lives, and it contains various subfolders based on Laravel's design pattern (MVC – Model, View, Controller).

  • app/Console/: Contains all custom Artisan commands for your project.

    • If you create custom commands using php artisan make:command, they will reside here.
  • app/Exceptions/: Handles custom exception classes and error handling.

    • Laravel has an ExceptionHandler.php here, which manages how exceptions are reported and rendered.
  • app/Http/: Handles everything related to HTTP requests.

    • Controllers/: Contains controllers that handle requests and responses, following the MVC architecture.
    • Middleware/: Contains middleware classes that filter HTTP requests before reaching controllers.
    • Kernel.php: Registers all your global and route-specific middleware.
  • app/Models/: Contains your Eloquent models, which represent the data structure in your database.

    • Example: User.php, Post.php.
  • app/Providers/: Contains service providers, which boot services like database connections or route binding.

    • AppServiceProvider.php: Registers application-wide services.
    • RouteServiceProvider.php: Defines how routes are loaded and handled.
    • AuthServiceProvider.php: Registers authentication services like policies and gates.
  • app/Policies/: Contains authorization policies that dictate which users can perform certain actions.

    • Policies allow you to centralize your business logic for authorization.
  • app/Jobs/: Holds job classes that are dispatched to handle asynchronous tasks in the background (queues).

  • app/Events/: Contains event classes, which trigger actions in your application, like broadcasting events to WebSockets or listeners.

  • app/Observers/: Observers allow you to watch for changes to Eloquent models, like when a record is created or updated.


2. bootstrap/ Folder

  • Purpose: Contains files for bootstrapping (starting) your application.
    • bootstrap/app.php: The core file that bootstraps the Laravel application and loads service providers.
    • cache/: This folder is used for storing framework-generated files, like compiled config or services, improving performance.

3. config/ Folder

  • Purpose: Contains configuration files for various parts of the framework (database, mail, services, queues, etc.).
    • Common files:
      • app.php: Application-level configuration.
      • database.php: Database connection details.
      • queue.php: Configuration for job queues.
      • mail.php: Mail configuration.
    • You can create your own configuration files if your project requires custom configuration parameters.

4. database/ Folder

  • Purpose: Manages database-related files and operations.
    • factories/: Contains model factory classes used to seed the database with fake data for testing.
    • migrations/: Contains migration files for creating and altering database tables.
    • seeders/: Contains seeder classes to populate your database with initial data, for example, users or posts.

5. public/ Folder

  • Purpose: This is the root folder for your web server (Nginx, Apache, etc.). The public files (like assets) live here.

    • index.php: The entry point for all HTTP requests. It bootstraps Laravel and routes the request to the correct controller.
    • assets/: Store static assets like images, CSS, JavaScript.

    When Laravel applications are deployed, the public folder is often the directory pointed to by the web server.


6. resources/ Folder

  • Purpose: This folder contains the application's front-end assets and view files.
    • views/: Contains Blade template files (.blade.php) that define the structure of your HTML pages.
    • lang/: Holds language files for localization, supporting multi-language applications.
    • js/: Contains JavaScript files for front-end assets (if you're not using Vite or Mix).
    • css/: Contains custom CSS files (if you're not using Vite or Mix).

7. routes/ Folder

  • Purpose: Contains all the route definitions for your application.
    • web.php: Contains routes for web requests that return views (HTML responses).
    • api.php: Defines routes for API requests, typically returning JSON responses.
    • console.php: Defines Artisan console commands.
    • channels.php: Contains routes for real-time WebSocket broadcasting channels.

8. storage/ Folder

  • Purpose: Stores files generated by the application like logs, caches, compiled views, and uploaded files.

    • app/: Stores files uploaded by the user or generated by your application.
    • logs/: Stores application logs (e.g., laravel.log), useful for debugging.
    • framework/: Contains framework-generated files such as cached views, sessions, and compiled files.
    • public/: Stores publicly accessible files that are linked to the public/ folder (e.g., images, documents).

    You often need to run php artisan storage:link to link this folder to the public directory.


9. tests/ Folder

  • Purpose: Contains all of your automated test files (unit and feature tests).

    • Feature/: Contains feature tests that simulate HTTP requests, test routes, and APIs.
    • Unit/: Contains unit tests that test the functionality of individual classes or methods.

    Laravel uses PHPUnit by default for testing, and the phpunit.xml file contains the testing configuration.


10. vendor/ Folder

  • Purpose: Contains all Composer dependencies, including the Laravel framework itself.

    • Note: You should never manually modify the contents of this folder.

    The vendor/ folder is generated by running composer install and includes all third-party packages.


11. Important Files at the Root Level

  • .env: The environment file where you define application-specific variables like database credentials, API keys, and environment modes (development, production). Never commit this file to version control, as it contains sensitive information.

  • artisan: A command-line utility to interact with Laravel, allowing you to perform tasks such as running migrations, generating controllers, or clearing caches.

  • composer.json: Defines the Composer dependencies and autoloading rules for your application. You can use this file to add/remove PHP packages via Composer.

  • package.json: Contains the Node.js dependencies for your application (if using front-end build tools like Vite or Laravel Mix).

  • phpunit.xml: Configuration for running automated tests using PHPUnit.

  • README.md: This file is a place where you document the project for other developers, providing setup instructions or details about the project.


Step 4: Create a Simple Route, Controller, and View

Step 4.1: Define a Route

  1. Open the routes/web.php file: You will define a simple route here.

  2. Add a New Route: Replace the existing route or add a new one:

    Route::get('/greet', function () {
        return view('greet', ['name' => 'Yugal']);
    });

    This defines a new route (/greet) and returns a view named greet with dynamic data (the name variable).


Step 4.2: Create a Controller

  1. Create a Controller: Use the artisan command to create a controller:

    php artisan make:controller GreetController
    
  2. Open the app/Http/Controllers/GreetController.php file.

  3. Add a Method to the Controller: In the GreetController, add the following code:

    <?php
    
    namespace App\Http\Controllers;
    
    use Illuminate\Http\Request;
    
    class GreetController extends Controller
    {
        public function show()
        {
            return view('greet', ['name' => 'Yugal']);
        }
    }
  4. Update the Route to Use the Controller: Update the routes/web.php to use the newly created controller update the route with controller and update the namesapce to add the controler:

    use App\Http\Controllers\GreetController;
    
    Route::get('/greet', [GreetController::class, 'show']);

Step 4.3: Create a View

  1. Create a New Blade Template: In the resources/views directory, create a new file called greet.blade.php.

  2. Add Content to the Blade Template: Open greet.blade.php and add the following HTML:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Greeting Page</title>
    </head>
    <body>
        <h1>Hello, {{ $name }}!</h1>
        <p>Welcome to your first Laravel page.</p>
    </body>
    </html>
  3. Verify the Result: Go to http://127.0.0.1:8000/greet in your browser, and you should see a page displaying:

    Hello, Yugal!
    Welcome to your first Laravel page.
    

Step 5: Laravel Artisan Commands Overview

Laravel comes with a command-line tool called Artisan that provides many helpful commands for development.

  1. List All Artisan Commands:

    php artisan list
    

    This will show all available Artisan commands.

  2. Create Model, Migration, Controller (Quick Command): Here’s how you can create a model, migration, and controller all at once:

    php artisan make:model Post -mc
    

    This creates a Post model, a corresponding migration file, and a controller.


Step 6: Push Code to GitHub (Optional)

  1. Initialize Git in the Project Directory:

    git init
    
  2. Add and Commit Files:

    git add .
    git commit -m "Initial Laravel setup"
    
  3. Push to GitHub: Create a new repository on GitHub, then push the code:

    git remote add origin <your-repo-url>
    git push -u origin main
    




2: Database Integration and Eloquent ORM

Objective:

  • Set up a database for the Laravel project.
  • Create and run migrations to manage the database schema.
  • Use Eloquent ORM for database interaction.
  • Perform basic CRUD operations with models.

Step 1: Set Up the Database Step 2: Create and Run Migrations

Step 2.1: Create a Migration for the "Posts" Table

  1. Generate a New Migration: Use the Artisan command to create a new migration file:

    php artisan make:migration create_posts_table
    

    This will create a migration file in the database/migrations directory.

  2. Open the Migration File: Navigate to database/migrations/<timestamp>_create_posts_table.php and define the schema for the posts table:

    <?php
    
    use Illuminate\Database\Migrations\Migration;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Support\Facades\Schema;
    
    class CreatePostsTable extends Migration
    {
        public function up()
        {
            Schema::create('posts', function (Blueprint $table) {
                $table->id();
                $table->string('title');
                $table->text('content');
                $table->timestamps();  // Adds 'created_at' and 'updated_at' fields
            });
        }
    
        public function down()
        {
            Schema::dropIfExists('posts');
        }
    }
  3. Run the Migration: Now, apply the migration to create the table in the database:

    php artisan migrate
    

    This will create the posts table in the database.

  4. Verify the Migration: Use a database tool (e.g., phpMyAdmin, PgAdmin) or command line to verify that the posts table has been created in your database.


Step 3: Create an Eloquent Model

Step 3.1: Generate the Post Model

  1. Create the Model: Use Artisan to generate a model for the posts table:

    php artisan make:model Post
    

    This creates the Post model in the app/Models directory.

  2. Define the Model Structure: Open the app/Models/Post.php file and make sure the model is set to interact with the posts table:

    <?php
    
    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Factories\HasFactory;
    use Illuminate\Database\Eloquent\Model;
    
    class Post extends Model
    {
        use HasFactory;
    
        // Specify which fields are mass assignable
        protected $fillable = ['title', 'content'];
    }

Step 4: Perform CRUD Operations with Eloquent

Step 4.1: Create Data Using Tinker

  1. Open Laravel Tinker: Tinker is an interactive shell that allows you to interact with your Laravel application:

    php artisan tinker
    
  2. Create a New Post: In the Tinker shell, create a new post using Eloquent:

    App\Models\Post::create(['title' => 'First Post', 'content' => 'This is the content of the first post.']);
  3. Fetch Posts: You can retrieve all posts using:

    App\Models\Post::all();
  4. Update a Post: Find and update a post by its ID:

    $post = App\Models\Post::find(1);
    $post->update(['title' => 'Updated Title']);
  5. Delete a Post: To delete a post:

    $post = App\Models\Post::find(1);
    $post->delete();
  6. Exit Tinker: To exit the Tinker shell, simply type:

    exit
    

Step 5: Add CRUD Functionality to the Application

Step 5.1: Create Routes for CRUD Operations

  1. Open the routes/web.php file and define routes for basic CRUD operations:
    use App\Http\Controllers\PostController;
    
    Route::get('/posts', [PostController::class, 'index']);
    Route::get('/posts/create', [PostController::class, 'create']);
    Route::post('/posts', [PostController::class, 'store']);
    Route::get('/posts/{id}', [PostController::class, 'show']);
    Route::get('/posts/{id}/edit', [PostController::class, 'edit']);
    Route::put('/posts/{id}', [PostController::class, 'update']);
    Route::delete('/posts/{id}', [PostController::class, 'destroy']);

Step 5.2: Create a PostController

  1. Generate the Controller:

    php artisan make:controller PostController --resource
    

    This generates a controller with methods for index, create, store, show, edit, update, and destroy.

  2. Implement CRUD Logic: Open app/Http/Controllers/PostController.php and implement the logic for each method. Here's an example for the index method:

    public function index()
    {
        $posts = Post::all();
        return view('posts.index', compact('posts'));
    }

Step 5.3: Create Views

  1. Create Blade Templates: Inside the resources/views/posts folder, create the following Blade templates:

    • index.blade.php: To display the list of posts.
    • create.blade.php: To create a new post.
    • edit.blade.php: To edit an existing post.

    Example for index.blade.php:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Posts</title>
    </head>
    <body>
        <h1>All Posts</h1>
        <ul>
            @foreach ($posts as $post)
                <li>{{ $post->title }}</li>
            @endforeach
        </ul>
    </body>
    </html>

namespace App\Http\Controllers;

use App\Models\Item;
use Illuminate\Http\Request;

class PostController extends Controller
{
    // Display a listing of the resource
    public function index()
    {
        $items = Item::all();
        return view('items.index', compact('items'));
    }

    // Show the form for creating a new resource
    public function create()
    {
        return view('items.create');
    }

    // Store a newly created resource in storage
    public function store(Request $request)
    {
        $validatedData = $request->validate([
            'name' => 'required|string|max:255',
            'description' => 'nullable|string',
        ]);

        Item::create($validatedData);
        return redirect()->route('items.index')->with('success', 'Item created successfully.');
    }

    // Display the specified resource
    public function show($id)
    {
        $item = Item::findOrFail($id);
        return view('items.show', compact('item'));
    }

    // Show the form for editing the specified resource
    public function edit($id)
    {
        $item = Item::findOrFail($id);
        return view('items.edit', compact('item'));
    }

    // Update the specified resource in storage
    public function update(Request $request, $id)
    {
        $item = Item::findOrFail($id);

        $validatedData = $request->validate([
            'name' => 'required|string|max:255',
            'description' => 'nullable|string',
        ]);

        $item->update($validatedData);
        return redirect()->route('items.index')->with('success', 'Item updated successfully.');
    }

    // Remove the specified resource from storage
    public function destroy($id)
    {
        $item = Item::findOrFail($id);
        $item->delete();
        return redirect()->route('items.index')->with('success', 'Item deleted successfully.');
    }
}


Step 6: Testing and Validation

  1. Test the Application:

    • Visit /posts in your browser to see the list of posts.
    • Add new posts via /posts/create.
    • Edit and delete posts using the corresponding routes.
  2. Add Validation: You can add form validation in the store and update methods using Laravel’s validation rules:

    $request->validate([
        'title' => 'required|max:255',
        'content' => 'required',
    ]);

outcome:

  • A fully functioning posts table in the database.
  • A Post model connected to the database.
  • Basic CRUD operations implemented using Eloquent ORM.
  • A set of routes and controllers to manage posts.
  • Blade views for displaying and managing posts.



3: Middleware, Authentication, and Authorization

Objective:

  • Understand and create middleware in Laravel.
  • Set up authentication using Laravel’s built-in Auth system.
  • Implement role-based authorization using policies or gates.

Step 1: Set Up Authentication Using Laravel’s Built-in System

Laravel provides built-in authentication scaffolding to handle user registration, login, and session management. We’ll use this system for authentication.

Step 1.1: Install Laravel Breeze for Authentication

  1. Install Laravel Breeze (a simple authentication scaffolding for Laravel): Run the following commands to install Laravel Breeze, which provides basic auth views and logic:

    composer require laravel/breeze --dev
    php artisan breeze:install
    
  2. Install Frontend Assets: After installing Breeze, run the following commands to install and build the frontend assets:

    npm install && npm run dev
    
  3. Migrate the Database: Laravel Breeze will have created the necessary database tables (for users, password resets, etc.). Run the migration to set up these tables:

    php artisan migrate
    
  4. Serve the Application: Start your local server to verify that authentication works:

    php artisan serve
    
  5. Test Authentication: Visit http://127.0.0.1:8000/register and http://127.0.0.1:8000/login to see the user registration and login forms. Register a new user and verify that login functionality works.


Step 2: Create Custom Middleware

Middleware allows you to filter HTTP requests entering your application. We’ll create custom middleware to restrict access to specific routes based on user roles.

Step 2.1: Generate Custom Middleware

  1. Create Middleware: Use the Artisan command to create new middleware:

    php artisan make:middleware EnsureUserIsAdmin
    
  2. Define the Middleware Logic: Open app/Http/Middleware/EnsureUserIsAdmin.php and define logic that checks if the user is an admin:

    <?php
    
    namespace App\Http\Middleware;
    
    use Closure;
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Auth;
    
    class EnsureUserIsAdmin
    {
        public function handle(Request $request, Closure $next)
        {
            // Check if user is authenticated and has the 'admin' role
            if (Auth::check() && Auth::user()->role !== 'admin') {
                return redirect('/'); // Redirect non-admin users
            }
    
            return $next($request);
        }
    }

Step 2.2: Apply Middleware to Routes

  1. Register Middleware: Open app/Http/Kernel.php and register the middleware in the $routeMiddleware array:

    protected $routeMiddleware = [
        // Other middleware
        'admin' => \App\Http\Middleware\EnsureUserIsAdmin::class,
    ];
  2. Apply Middleware to Routes: Open routes/web.php and apply the middleware to specific routes. For example, if you have an admin dashboard route:

    Route::get('/admin/dashboard', [AdminController::class, 'index'])->middleware('admin');
  3. Test Middleware: Try accessing the /admin/dashboard route as a regular user (without the 'admin' role) to confirm the middleware is working and redirects you.


Step 3: Role-Based Authorization Using Gates or Policies

Laravel’s authorization system allows you to restrict user actions based on their roles. We will use either Gates or Policies for fine-grained access control.

Step 3.1: Add a Role Column to Users

  1. Create a Migration to Add the Role Column: Run the Artisan command to create a migration:

    php artisan make:migration add_role_to_users_table --table=users
    
  2. Update the Migration File: In the migration file, add the following code to add a role column to the users table:

    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->string('role')->default('user'); // Adding a 'role' column
        });
    }
    
    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn('role');
        });
    }
  3. Run the Migration: Run the migration to apply the changes to the database:

    php artisan migrate
    
  4. Set User Roles: In phpMyAdmin or any database management tool, update the role field for your admin user:

    • Set the role to admin for an admin user.
    • Set the role to user for a regular user.

Step 3.2: Implement Authorization Using Gates

  1. Define a Gate: Gates are a simple closure-based authorization system in Laravel. Open app/Providers/AuthServiceProvider.php and define a gate that checks if a user is an admin:

    use Illuminate\Support\Facades\Gate;
    
    public function boot()
    {
        $this->registerPolicies();
    
        Gate::define('access-admin-dashboard', function ($user) {
            return $user->role === 'admin';
        });
    }
  2. Use the Gate in Controllers or Views: You can use the Gate::allows() method in controllers or views to check permissions:

    if (Gate::allows('access-admin-dashboard')) {
        // The current user can access the admin dashboard
    }
  3. Restrict Access in Blade Views: Use the @can directive in Blade views to show content only to authorized users:

    @can('access-admin-dashboard')
        <a href="/admin/dashboard">Admin Dashboard</a>
    @endcan

Step 3.3: Implement Authorization Using Policies (Optional)

If your application requires more complex authorization rules, you can use Policies.

  1. Generate a Policy: Use Artisan to generate a policy for the Post model:

    php artisan make:policy PostPolicy
    
  2. Define Policy Methods: Open app/Policies/PostPolicy.php and define the authorization logic. For example:

    public function update(User $user, Post $post)
    {
        return $user->role === 'admin'; // Only admin can update posts
    }
  3. Register the Policy: Open app/Providers/AuthServiceProvider.php and register the policy:

    use App\Models\Post;
    use App\Policies\PostPolicy;
    
    protected $policies = [
        Post::class => PostPolicy::class,
    ];
  4. Use the Policy in Controllers or Views: You can use the authorize method in your controller to check for permissions:

    $this->authorize('update', $post);

Step 4: Testing Authentication and Authorization

  1. Test Registration and Login:

    • Register a new user using the /register route.
    • Log in using the /login route.
  2. Test Role-Based Access:

    • As a regular user, try accessing the /admin/dashboard route. You should be redirected to the home page or another route based on your middleware logic.
    • As an admin user, verify that you can access the admin dashboard.
  3. Test Authorization with Gates:

    • Add admin links in the Blade views that should only be visible to admin users.
    • Ensure that only users with the admin role can see or perform restricted actions.

outcomes:

  • Authentication system fully implemented using Laravel Breeze.
  • Custom middleware to restrict access to admin-only pages.
  • Role-based access control using Gates or Policies.
  • Proper authorization checks applied in both the backend and frontend (Blade views).



Day 4: Frontend Integration with Vite and Livewire

Objective:

  • Set up and integrate Vite to manage frontend assets like JavaScript and CSS.
  • Implement Livewire to create interactive frontend components in Laravel without needing a full page reload.
  • Understand and use Hot Module Replacement (HMR) for faster development.

Step-by-Step Instruction:

Step 1: Setting Up Vite in a New or Existing Laravel Project

Vite is now the default for managing assets in Laravel (from version 9 onward). It offers faster development with Hot Module Replacement (HMR) and builds production-ready assets.

Step 1.1: Install Node.js and NPM (if not already installed)

Make sure you have Node.js and NPM installed on your machine. You can install Node.js by downloading it from the official Node.js website.

Check if Node.js and NPM are already installed by running:

node -v
npm -v

Step 1.2: Install NPM Dependencies for Vite

In your Laravel project root directory, install the NPM dependencies for Vite:

npm install

This installs all the required Node.js modules to manage frontend assets, including the Vite build tool.


Step 2: Basic Vite Configuration in Laravel

Once Vite is installed, ensure the default Vite configuration works in your project.

Step 2.1: Modify Blade Template to Use Vite

Ensure your resources/views/welcome.blade.php (or any layout Blade file) is using Vite for managing assets instead of Laravel Mix:

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Laravel with Vite</title>

    <!-- Include Vite CSS -->
    @vite('resources/css/app.css')
</head>
<body>
    <div id="app">
        @yield('content')
    </div>

    <!-- Include Vite JavaScript -->
    @vite('resources/js/app.js')
</body>
</html>

Step 2.2: Run Vite Development Server

For local development, run the Vite development server. This enables Hot Module Replacement (HMR), allowing you to see changes immediately in the browser without refreshing.

Run the following command:

npm run dev

This starts the Vite development server, compiling CSS and JavaScript files and enabling HMR. You can now work on your frontend files (CSS and JS) in resources/ and see the changes reflected instantly.

Visit http://localhost:3000 to verify that everything is working.


Step 3: Integrating Livewire for Frontend Interactivity

Livewire is a full-stack framework for Laravel that allows you to create dynamic, reactive UI components without writing much JavaScript.

Step 3.1: Install Livewire

Use Composer to install the Livewire package:

composer require livewire/livewire

Step 3.2: Include Livewire in Blade Templates

In your main layout file (e.g., resources/views/layouts/app.blade.php), add the Livewire styles and scripts inside the <head> and before the closing </body> tag:

<head>
    @livewireStyles
</head>
<body>
    <!-- Your content goes here -->

    @livewireScripts
</body>

Step 3.3: Create a Livewire Component

Run the following Artisan command to generate a new Livewire component:

php artisan make:livewire ExampleComponent

This command will create two files:

  • app/Http/Livewire/ExampleComponent.php (the component class).
  • resources/views/livewire/example-component.blade.php (the Blade view for the component).

Step 3.4: Implement Livewire Component

In app/Http/Livewire/ExampleComponent.php, define some properties and methods for your component. For example, a simple counter:

namespace App\Http\Livewire;

use Livewire\Component;

class ExampleComponent extends Component
{
    public $count = 0;

    public function increment()
    {
        $this->count++;
    }

    public function render()
    {
        return view('livewire.example-component');
    }
}

In the Blade file resources/views/livewire/example-component.blade.php, define the frontend part of your component:

<div>
    <h1>{{ $count }}</h1>
    <button wire:click="increment">Increment</button>
</div>

This creates a dynamic counter that increments without a full page reload whenever the "Increment" button is clicked.

Step 3.5: Add Livewire Component to a Page

You can add this component to any Blade template by including the Livewire component directive. For example, add it to resources/views/welcome.blade.php or resources/views/home.blade.php:

<livewire:example-component />

Step 3.6: Test the Livewire Component

Serve the application using:

php artisan serve

Visit http://127.0.0.1:8000 (or your local URL) and test the interactive Livewire component.


Step 4: Build for Production with Vite

After you're done with development, it's time to build the production-ready assets. Vite will compile and minify your CSS and JavaScript for faster performance in production.

Run the following command to build the assets for production:

npm run build

This command compiles your frontend assets into optimized files, typically saved in the public/build/ directory.


Step 5: Additional Livewire Features (Optional)

Here are some additional features you can explore with Livewire:

  • Real-Time Validation: Validate form inputs in real-time.
  • Emit and Listen to Events: Trigger and handle events between components.
  • Dynamic UI Updates: Update parts of the page dynamically without refreshing the whole page.

For example, you can add real-time validation by creating a form with Livewire:

public $name;

public function updatedName()
{
    $this->validate([
        'name' => 'required|min:6',
    ]);
}

  1. Vite set up for managing frontend assets and using Hot Module Replacement (HMR) for fast development.
  2. A basic Livewire component implemented to make the frontend interactive without writing JavaScript.
  3. Understood how to build assets for production using Vite.

Commands Summary:

  1. Install NPM dependencies:

    npm install
    
  2. Run Vite development server with HMR:

    npm run dev
    
  3. Install Livewire:

    composer require livewire/livewire
    
  4. Create a Livewire component:

    php artisan make:livewire ExampleComponent
    
  5. Serve Laravel application:

    php artisan serve
    
  6. Build assets for production:

    npm run build
    



5: Testing in Laravel

Objective:

  • Understand how to write and run Unit Tests and Feature Tests using PHPUnit.
  • Test various components of the application such as models, controllers, API endpoints, and Livewire components.
  • Ensure that the previously built features (CRUD, API, Livewire components) are working as expected through automated testing.

Step-by-Step Instruction:


Step 1: Introduction to Testing in Laravel

Laravel includes PHPUnit by default and provides useful testing helpers to easily test the functionality of your application.

  • Unit Tests focus on testing small, isolated pieces of your code (e.g., model methods).
  • Feature Tests focus on testing larger pieces like routes, controllers, and APIs.

Laravel also has built-in testing capabilities for Livewire components to ensure they work as expected.


Step 2: Setting Up Testing Environment

Laravel uses a separate environment for running tests, which you need to configure.

Step 2.1: Duplicate .env File for Testing Create a separate .env.testing file for the testing environment:

cp .env .env.testing

Step 2.2: Configure the Testing Database Open the .env.testing file and set it up to use an SQLite database (or any other lightweight database):

DB_CONNECTION=sqlite
DB_DATABASE=:memory:

Laravel will use an in-memory SQLite database to run tests, ensuring that your actual database remains unaffected.


Step 3: Writing Unit Tests

Unit tests ensure that the core logic in your application works as expected. We will write unit tests for a Post model.

Step 3.1: Create a Unit Test for the Post Model

Run the following command to generate a unit test for the Post model:

php artisan make:test PostTest --unit

This command will create a PostTest.php file in the tests/Unit/ directory.

Step 3.2: Write Test Cases for the Post Model

Open tests/Unit/PostTest.php and write test cases. For example, to test post creation and validation:

namespace Tests\Unit;

use Tests\TestCase;
use App\Models\Post;
use Illuminate\Foundation\Testing\RefreshDatabase;

class PostTest extends TestCase
{
    use RefreshDatabase;

    / @test */
    public function it_can_create_a_post()
    {
        $post = Post::create([
            'title' => 'Sample Post',
            'content' => 'This is the content of the post.',
        ]);

        $this->assertDatabaseHas('posts', ['title' => 'Sample Post']);
    }
}

This test checks if a Post can be created and if it is saved in the database.

Step 3.3: Run Unit Tests

To run the unit tests, use:

php artisan test --filter=PostTest

Step 4: Writing Feature Tests

Feature tests allow you to test how multiple pieces of the application work together (e.g., routes, controllers, APIs).

Step 4.1: Create a Feature Test for the API

To test the API that was built in Day 6, run the following command:

php artisan make:test PostApiTest

This will generate a test file in the tests/Feature/ directory.

Step 4.2: Write Feature Test for the API Endpoints

Open tests/Feature/PostApiTest.php and write test cases for the API endpoints.

  1. Test for Fetching All Posts:

    public function test_can_fetch_all_posts()
    {
        Post::factory()->count(3)->create();
    
        $response = $this->getJson('/api/posts');
    
        $response->assertStatus(200)
                 ->assertJsonCount(3);
    }
  2. Test for Creating a Post via API:

    public function test_can_create_a_post()
    {
        $postData = [
            'title' => 'New Post',
            'content' => 'Content for the new post.',
        ];
    
        $response = $this->postJson('/api/posts', $postData);
    
        $response->assertStatus(201)
                 ->assertJson(['title' => 'New Post']);
    
        $this->assertDatabaseHas('posts', ['title' => 'New Post']);
    }

Step 4.3: Run Feature Tests

Run the feature tests to verify the API:

php artisan test --filter=PostApiTest

Step 5: Testing Livewire Components

Laravel provides built-in support for testing Livewire components. Let’s test the Livewire component created in Day 4 (e.g., a counter component).

Step 5.1: Create a Livewire Test

Run the following command to generate a test for a Livewire component:

php artisan make:test LivewireCounterTest

Step 5.2: Write Livewire Test

Open tests/Feature/LivewireCounterTest.php and write test cases for the component.

Example of testing a counter component where clicking the button increments the counter:

namespace Tests\Feature;

use Livewire\Livewire;
use Tests\TestCase;

class LivewireCounterTest extends TestCase
{
    / @test */
    public function it_increments_the_counter()
    {
        Livewire::test('counter')
            ->call('increment')
            ->assertSee(1);
    }
}

Step 5.3: Run Livewire Component Tests

Run the Livewire tests to ensure the components are functioning correctly:

php artisan test --filter=LivewireCounterTest

Step 6: Running All Tests

After writing all the tests (unit, feature, and Livewire tests), you can run all tests together using:

php artisan test

Laravel will run all the tests in the tests/Unit and tests/Feature directories and output the results.


Step 7: Continuous Testing and Integration

  • Encourage the team to integrate testing into their daily development workflow.
  • For larger projects, integrate testing into your CI/CD pipeline to ensure that all tests are automatically run on every push or pull request.

Outcome:

  1. Understand and write unit tests for individual model methods.
  2. Write and execute feature tests for routes, controllers, and APIs.
  3. Implement Livewire component testing to ensure dynamic frontend functionality works correctly.
  4. Use PHPUnit to run automated tests and verify the correctness of application features.



6: Filament Admin Panel Introduction

Objective:

  • Install and configure Filament in the Laravel project.
  • Create a basic CRUD interface using Filament.
  • Customize Filament resources (forms, tables) for a specific model.
  • Apply role-based access control for the admin panel.

Step 1: Install Filament in Laravel

Filament is a lightweight admin panel generator that allows you to create and manage resources easily. It is designed specifically for Laravel and integrates well with the Eloquent ORM.

Step 1.1: Install Filament In the terminal, run the following command to install Filament via Composer:

composer require filament/filament

Step 1.2: Publish Filament Assets Once installed, publish the Filament configuration and assets:

php artisan filament:install

This command will create necessary configuration files and assets for Filament.

Step 1.3: Run Migrations Filament also requires some database migrations for user roles and permissions. Run the migrations to set up these tables:

php artisan migrate

Step 1.4: Access the Admin Panel Now, start the Laravel development server:

php artisan serve

Visit http://127.0.0.1:8000/admin to access the Filament admin panel. You should see the Filament login page. Create a user by registering or logging in with an existing user.


Step 2: Creating a Filament Resource for a Model

We’ll now create a Filament resource to manage a model, like Post.

Step 2.1: Create the Post Model and Migration

If you don’t already have the Post model from Day 2, you can create it using Artisan:

php artisan make:model Post -m

Edit the migration file in database/migrations to add the necessary fields for the posts table:

Schema::create('posts', function (Blueprint $table) {
    $table->id();
    $table->string('title');
    $table->text('content');
    $table->timestamps();
});

Run the migration:

php artisan migrate

Step 2.2: Generate a Filament Resource

Use the following command to generate a Filament resource for the Post model:

php artisan make:filament-resource Post

This will generate a resource file located at app/Filament/Resources/PostResource.php along with default views for listing, creating, and editing posts.

Step 2.3: Customize the Post Resource

Open app/Filament/Resources/PostResource.php. You will see predefined configurations for fields and forms. Customize the table and form based on your needs.

  1. Defining Table Columns: Modify the table() method to define how the table should display the posts in the admin panel:

    public static function table(Table $table): Table
    {
        return $table
            ->columns([
                TextColumn::make('title')->sortable(),
                TextColumn::make('created_at')->dateTime()->label('Created'),
            ])
            ->filters([
                //
            ]);
    }
  2. Defining Form Fields: Modify the form() method to define the fields users will fill out when creating or editing posts:

    public static function form(Form $form): Form
    {
        return $form
            ->schema([
                TextInput::make('title')->required(),
                Textarea::make('content')->required(),
            ]);
    }

Step 3: Customize Filament Features (Forms, Tables)

Filament provides a range of tools to customize the admin panel’s look and feel. Here’s how you can extend the functionality of your admin panel.

Step 3.1: Adding Filters to the Table

You can add filters to the table to allow admins to quickly find posts based on certain criteria:

public static function table(Table $table): Table
{
    return $table
        ->columns([
            TextColumn::make('title')->sortable(),
            TextColumn::make('created_at')->dateTime(),
        ])
        ->filters([
            SelectFilter::make('created_at')
                ->label('Filter by Date')
                ->options([
                    'today' => 'Today',
                    'this_week' => 'This Week',
                    'this_month' => 'This Month',
                ]),
        ]);
}

Step 3.2: Adding Validation to Forms

To ensure data integrity, add validation to the form fields. For example:

public static function form(Form $form): Form
{
    return $form
        ->schema([
            TextInput::make('title')
                ->required()
                ->maxLength(255)
                ->label('Post Title'),
            Textarea::make('content')
                ->required()
                ->label('Post Content'),
        ]);
}

Step 4: Implement Role-Based Access Control for the Admin Panel

You can restrict access to certain parts of the admin panel based on user roles.

Step 4.1: Add a Role Column to Users

If you haven’t already done so in Day 3, add a role column to the users table via migration:

php artisan make:migration add_role_to_users_table --table=users

Edit the migration to add the role column:

Schema::table('users', function (Blueprint $table) {
    $table->string('role')->default('user');
});

Run the migration:

php artisan migrate

Step 4.2: Assign Roles to Users

Manually update the role field in the database for users. You can use phpMyAdmin or any database management tool to assign the role of admin or user to each user.

Step 4.3: Restrict Access to the Admin Panel

To restrict access to the admin panel based on roles, open app/Providers/FilamentServiceProvider.php and modify the gate() method:

use Illuminate\Support\Facades\Gate;

public function boot()
{
    Filament::serving(function () {
        Gate::define('access-filament', function ($user) {
            return $user->role === 'admin';  // Only admins can access the admin panel
        });
    });
}

Now, only users with the admin role will have access to the Filament admin panel.


Step 5: Testing the Admin Panel

  1. Visit the Admin Panel: Visit http://127.0.0.1:8000/admin in your browser. If you are logged in as an admin, you should see the Post resource listed in the sidebar.

  2. Create, Edit, and Delete Posts:

    • Use the admin panel to create a new post.
    • Edit existing posts by clicking the “Edit” button.
    • Delete posts using the “Delete” button.
  3. Test Role-Based Access:

    • Log in as a user with the user role and try accessing the /admin route. You should be denied access.

Step 6: Additional Customizations (Optional)

Step 6.1: Customizing Admin Navigation

You can customize the navigation in the admin panel by modifying the PostResource.php file:

public static function getNavigationLabel(): string
{
    return 'Blog Posts';
}

Step 6.2: Creating Custom Pages or Widgets

Filament allows you to create custom pages and widgets within the admin panel. For example, you can create a dashboard with statistics about the posts or users.

  1. Generate a Dashboard Widget:

    php artisan make:filament-widget PostStatsWidget
    
  2. Customize the Widget: Edit the newly created widget in app/Filament/Widgets/PostStatsWidget.php to display statistics like total posts, recent posts, etc.


Outcome:

  • A fully functioning Filament admin panel.
  • CRUD operations implemented for the Post model using Filament.
  • Role-based access control applied to the admin panel.
  • Customized forms, tables, and navigation in the admin panel.



For next part visit this link: https://gist.github.com/YugalXD/f66f714f1ca60fb4ec4826d4fda97030

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment