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:
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.
- If you create custom commands using
-
app/Exceptions/
: Handles custom exception classes and error handling.- Laravel has an
ExceptionHandler.php
here, which manages how exceptions are reported and rendered.
- Laravel has an
-
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
.
- Example:
-
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.
- 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.
- 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.
- Common files:
- 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.
-
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.
- 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).
- 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.
-
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 thepublic/
folder (e.g., images, documents).
You often need to run
php artisan storage:link
to link this folder to the public directory.
-
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.
-
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 runningcomposer install
and includes all third-party packages.
-
.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
-
Open the
routes/web.php
file: You will define a simple route here. -
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 namedgreet
with dynamic data (thename
variable).
Step 4.2: Create a Controller
-
Create a Controller: Use the
artisan
command to create a controller:php artisan make:controller GreetController
-
Open the
app/Http/Controllers/GreetController.php
file. -
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']); } }
-
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
-
Create a New Blade Template: In the
resources/views
directory, create a new file calledgreet.blade.php
. -
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>
-
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.
-
List All Artisan Commands:
php artisan list
This will show all available Artisan commands.
-
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)
-
Initialize Git in the Project Directory:
git init
-
Add and Commit Files:
git add . git commit -m "Initial Laravel setup"
-
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
-
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. -
Open the Migration File: Navigate to
database/migrations/<timestamp>_create_posts_table.php
and define the schema for theposts
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'); } }
-
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. -
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
-
Create the Model: Use Artisan to generate a model for the
posts
table:php artisan make:model Post
This creates the
Post
model in theapp/Models
directory. -
Define the Model Structure: Open the
app/Models/Post.php
file and make sure the model is set to interact with theposts
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
-
Open Laravel Tinker: Tinker is an interactive shell that allows you to interact with your Laravel application:
php artisan tinker
-
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.']);
-
Fetch Posts: You can retrieve all posts using:
App\Models\Post::all();
-
Update a Post: Find and update a post by its ID:
$post = App\Models\Post::find(1); $post->update(['title' => 'Updated Title']);
-
Delete a Post: To delete a post:
$post = App\Models\Post::find(1); $post->delete();
-
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
- 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
-
Generate the Controller:
php artisan make:controller PostController --resource
This generates a controller with methods for index, create, store, show, edit, update, and destroy.
-
Implement CRUD Logic: Open
app/Http/Controllers/PostController.php
and implement the logic for each method. Here's an example for theindex
method:public function index() { $posts = Post::all(); return view('posts.index', compact('posts')); }
Step 5.3: Create Views
-
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
-
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.
- Visit
-
Add Validation: You can add form validation in the
store
andupdate
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
-
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
-
Install Frontend Assets: After installing Breeze, run the following commands to install and build the frontend assets:
npm install && npm run dev
-
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
-
Serve the Application: Start your local server to verify that authentication works:
php artisan serve
-
Test Authentication: Visit
http://127.0.0.1:8000/register
andhttp://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
-
Create Middleware: Use the Artisan command to create new middleware:
php artisan make:middleware EnsureUserIsAdmin
-
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
-
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, ];
-
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');
-
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
-
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
-
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'); }); }
-
Run the Migration: Run the migration to apply the changes to the database:
php artisan migrate
-
Set User Roles: In
phpMyAdmin
or any database management tool, update therole
field for your admin user:- Set the role to
admin
for an admin user. - Set the role to
user
for a regular user.
- Set the role to
Step 3.2: Implement Authorization Using Gates
-
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'; }); }
-
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 }
-
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.
-
Generate a Policy: Use Artisan to generate a policy for the
Post
model:php artisan make:policy PostPolicy
-
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 }
-
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, ];
-
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
-
Test Registration and Login:
- Register a new user using the
/register
route. - Log in using the
/login
route.
- Register a new user using the
-
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.
- As a regular user, try accessing the
-
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',
]);
}
- Vite set up for managing frontend assets and using Hot Module Replacement (HMR) for fast development.
- A basic Livewire component implemented to make the frontend interactive without writing JavaScript.
- Understood how to build assets for production using Vite.
Commands Summary:
-
Install NPM dependencies:
npm install
-
Run Vite development server with HMR:
npm run dev
-
Install Livewire:
composer require livewire/livewire
-
Create a Livewire component:
php artisan make:livewire ExampleComponent
-
Serve Laravel application:
php artisan serve
-
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.
-
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); }
-
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:
- Understand and write unit tests for individual model methods.
- Write and execute feature tests for routes, controllers, and APIs.
- Implement Livewire component testing to ensure dynamic frontend functionality works correctly.
- 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.
-
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([ // ]); }
-
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
-
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 thePost
resource listed in the sidebar. -
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.
-
Test Role-Based Access:
- Log in as a user with the
user
role and try accessing the/admin
route. You should be denied access.
- Log in as a user with the
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.
-
Generate a Dashboard Widget:
php artisan make:filament-widget PostStatsWidget
-
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