LARAVEL WEB APP DEVELOPMENT
LARAVEL
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
WHY LARAVEL IS POPULAR
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
INSTALL LARAVEL APP
composer create-project --prefer-dist laravel/laravel <project_name> “5.7.*"
php artisan serve
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
BASIC ROUTING
In the routes/web.php, add the new route called contact and return the
view
Create the new file in views/contact.blade.php
Route::get('/contact', function() {
return view('contact');
});
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
BLADE LAYOUT FILES
Create a new folder and file called views/layouts/master.blade.php
Write the html code in master.blade and add @yield for the content in the body tag
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About Us</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
{{-- Content --}}
@yield('content')
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
BLADE LAYOUT FILES
Change the title into @yield in the master blade layout file
Change the title by @section in About Us , Contact us page.
<head>
...
<title> @yield('title', 'Laravel Web App’) </title>
</head>
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
BLADE LAYOUT FILES
Use this template in welcome , about and contact layout page
@extends('layouts.master')
@section('title', 'Contact')
@section('content')
<h1> Contact Form </h1>
...
@endsection
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
SENDING DATA TO YOUR VIEWS
Pass the array of tasks into the views in routes/web.php
Use the @foreach to print the array of tasks in welcome.blade.php
Route::get('/', function () {
$tasks = [
'Go to store ',
'Go to market ',
'Go to work '
];
return view('welcome', [
'tasks' => $tasks
]);
});
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
SENDING DATA TO YOUR VIEWS
Use the @foreach to print the array of tasks in welcome.blade.php
@extends('layouts.master')
@section('content')
<h1> Here we go !</h1>
<ul>
@foreach ($tasks as $task)
<li> {{ $task }} </li>
@endforeach
</ul>
@endsection
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
CONTROLLERS 101
Create the new controller via : php artisan make:controller PagesController
Change all of the routes into controller@function_name
Route::get('/', 'PagesController@home');
Route::get('/about', 'PagesController@about');
Route::get('/contact', 'PagesController@contact');
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
CONTROLLERS 101
Add the home function in Http/controllers/PagesController.php
// About Page
// Home Page
public function about()
public function home()
{
{
return view('about');
$tasks = [
}
'Go to store ',
// Contact Page
'Go to market ',
public function contact()
'Go to work '
{
];
return view('contact');
return view('welcome', [
}
'tasks' => $tasks
]);
}
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
DATABASES AND MIGRATIONS
Setting up the environment variable for database configuration in .env
Create the new database table in phpmyadmin called project_db
Run the command : php artisan migrate
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=project_db
DB_USERNAME=root
DB_PASSWORD=
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
DATABASES AND MIGRATIONS
Run the command : php artisan make:migration create_projects_table
Write this schema database/migrations/…_create_project_table.php
Schema::create('projects', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->longtext(‘description');
$table->timestamps();
});
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
ELOQUENT, NAMESPACING, AND MVC
Run the command : php artisan make:model Project
Insert the data via tinker : php artisan tinker
$project = new App\Project;
$project->title = "My first Project";
$project->description = "Project one
description ";
$project->save();
App\Project::all();
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
ELOQUENT, NAMESPACING, AND MVC
Run the command : php artisan make:model Project
Insert the data via tinker : php artisan tinker
Write this code inside the terminal
$project = new App\Project;
$project->title = "My first Project";
$project->description = "Project one
description ";
$project->save();
App\Project::all();
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
ELOQUENT, NAMESPACING, AND MVC
Run the command : php artisan make:model Project
Goal: Show the Projects lists in url /projects
1.Insert
Createthe
the data via tinker
new route : php
in web.php to artisan tinker
controler@index
2. Create Projects controller via artisan command
3. Use the Project::all() in the controller
4. Pass the data projects into views
4. Test your work!
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
FORM HANDLING
Create a new route called “projects/create” in web.php
Route::post('/projects', ‘ProjectsController@store');
Route::get('/projects/create', 'ProjectsController@create');
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
FORM HANDLING
Write a new function called create() in the ProjectsController
{{ csrf_field() }}
Make an new view projects/create.blade.php
Write the form …
public function create()
{
return view('projects.create');
}
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
FORM HANDLING
Write a new function called store() in the ProjectsController
// Save the project
public function store()
{
$project = new Project();
$project->title = request('title');
$project->description = request('description');
$project->save();
return redirect('/projects');
}
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
ROUTING CONVENTION
Write a new function called store() in the ProjectsController
proj
G
proje ects.
E
cts inde
T
x
proje proje
G
cts/ cts.c
E
creat reat
T
e e
proje
proj
G cts/
ects.
E{proj
sho
T ect_i
w
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
ROUTING CONVENTION
Change the resource route in web.php
// Route::get('/projects', 'ProjectsController@index');
// Route::post('/projects', 'ProjectsController@store');
// Route::get('/projects/create', 'ProjectsController@create');
Route::resource('/projects', 'ProjectsController');
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
FAKING PATCH AND DELETE REQUESTS
Create the new function called edit($id) in the ProjectsController.php
// Edit the project
public function edit($id)
{
$project = Project::findOrFail($id);
return view('projects.edit', compact('project'));
}
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
FAKING PATCH AND DELETE REQUESTS
Create a new form in views/projects/edit.blade.php
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
FAKING PATCH AND DELETE REQUESTS
Simple code for the project edit page
<form method="POST" action="/projects/{{ $project->id }}">
{{ method_field('PATCH') }}
{{ csrf_field() }}
<input value="{{ $project->title }}" type="text" name="title">
<textarea name="description">{{ $project->description }}</textarea>
<button type="submit">Update Project</button>
</form>
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
FAKING PATCH AND DELETE REQUESTS
Add the new function called update($id) in the ProjectsController.php
public function update($id)
{
$project = Project::findOrFail($id);
$project->title = request('title');
$project->description = request('description');
$project->save();
return redirect('/projects');
}
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
FAKING PATCH AND DELETE REQUESTS
Add the new function called destroy($id) in the ProjectsController.php
public function destroy($id)
{
$project = Project::findOrFail($id)->delete();
return redirect('/projects');
}
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
FAKING PATCH AND DELETE REQUESTS
Add the new form with the delete button in edit.blade.php
<form method="POST" action="/projects/{{ $project->id }}" style="margin-top:20px;">
@method('DELETE')
@csrf
<div class="form-group">
<button class="btn btn-danger" type="submit">Delete Project</button>
</div>
</form>
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
DISPLAY THE PROJECT
Add the new form with the delete button in edit.blade.php
// Show the project
public function show($id)
{
$project = Project::findOrFail($id);
return view('projects.show', compact('project'));
}
TIME TO
REFACTOR
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
ROUTE MODEL BINDING
Change the parameter id to model object in the ProjectsController
// Show the project
public function show(Project $project)
{
return view('projects.show', compact('project'));
}
// Save the project
public function store(Project $project)
{
$project->create(request(['title','description']));
return redirect('/projects');
}
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
ROUTE MODEL BINDING
Change the parameter id to model object in the ProjectsController
// Edit the project
public function edit(Project $project)
{
return view('projects.edit', compact('project'));
}
public function update(Project $project)
{
$project->update(request(['title','description']));
return redirect('/projects');
}
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
ROUTE MODEL BINDING
Change the parameter id to model object in the ProjectsController
// Delete the project
public function destroy(Project $project)
{
$project->delete();
return redirect('/projects');
}
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
ROUTE MODEL BINDING
Add the guarded array for the id key avoid to use in mass assignment
class Project extends Model
{
protected $guarded = ['id'];
// Change the Route Key Name
public function getRouteKeyName()
{
return 'title';
}
}
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
TWO LAYERS OF VALIDATION
There are two layers of validation process : client site and server site
Use the validation function in request in store () & update ()
request()->validate([
'title' => 'required|min:3',
'description' => 'required|min:3',
])
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
TWO LAYERS OF VALIDATION
Add the server site validation messages in create.blade.php
<!-- Show the error Message -->
@include('projects.message')
...
<input class="form-control {{ $errors->has('title') ? 'is-invalid' : ‘' }}"
type="text"
name="title"
placeholder="Project Title"
value="{{ old('title') }}”
>
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
TWO LAYERS OF VALIDATION
Create the new blade file in projects/message.blade.php
<!-- Show the errors -->
@if($errors->any())
<div class="alert alert-danger alert-dismissible fade show" role="alert">
<ul>
@foreach($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
FIRST ELOQUENT RELATIONSHIP
Create the new model called Tasks
php artisan make:model Task -m -f
// create_tasks_table.php
Schema::create('tasks', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger(‘project_id');
$table->string('description');
$table->boolean('completed')->default(false);
$table->timestamps();
});
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
FIRST ELOQUENT RELATIONSHIP
Create the relationship with Project Model
Use the HasMany relationship because one project has many tasks …
class Project extends Model
{
...
public function tasks()
{
return $this->hasMany(Task::Class);
}
}
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
FIRST ELOQUENT RELATIONSHIP
Inversely , each task has belongs with one project
So, use the belongsTo relationship for the project model
class Task extends Model
{
// Belongs with the project
public function project()
{
return $this->belongsTo(Project::class);
}
}
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
FIRST ELOQUENT RELATIONSHIP
Show the lists of tasks in projects/show.blade.php
@if ($project->tasks->count())
<div>
@foreach ($project->tasks as $task)
<li> {{ $task->description }}</li>
@endforeach
</div>
@endif
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
FORM ACTION CONSIDERATIONS
Create the new route for patch request update protected $guarded = [‘id'];
php artisan make:controller ProjectTasksController -r
Route::patch('/tasks/{task}', 'ProjectTasksController@update');
public function update(Task $task)
{
// Update the tasks
$task->update([
'completed' => request()->has('completed')
]);
return back();
}
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
FORM ACTION CONSIDERATIONS
Change the lists of tasks in projects/show.blade.php
@foreach ($project->tasks as $task)
<div class="tasks">
<form method="post" action="/tasks/{{ $task->id }}">
@csrf
@method('PATCH')
<label class="{{ $task->completed ? 'completed' : '' }}" for="completed">
<input type="checkbox" name="completed"
onChange="this.form.submit()" {{ $task->completed ? 'checked' : '' }}>
{{ $task->description }}
</label>
</form>
</div>
@endforeach
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
CREATE NEW PROJECT TASKS
Create new task form in projects/show.blade.php
<form method="post" action="/projects/{{ $project->title }}/tasks">
@csrf
<div class="form-group">
<input class="form-control {{ $errors->has('description') ? 'is-invalid': ''}}"
type="text" name="description"
placeholder="New Task">
</div>
</form>
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
CREATE NEW PROJECT TASKS
Create the new route for POST request of projects tasks
Route::post('/projects/{project}/tasks', 'ProjectTasksController@store');
public function store(Project $project)
{
// Create new fun in Project model
// Validate the requests
public function addTask($task)
$attributes = request()->validate([
{
'description' => 'required|min:3'
$this->tasks()->create($task);
]);
}
$project->addTask($attributes);
return back();
}
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
BETTER ENCAPSULATION
Change the encapsulation for the tasks completed
public function update(Task $task)
{
// Update the completed tasks
request()->has('completed') ? $task->complete() : $task->incomplete();
return back();
}
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
BETTER ENCAPSULATION
Write the new method in model for the tasks complete / incomplete
class Task extends Model
{
...
public function complete($completed = true)
{
$this->update(compact('completed'));
}
public function incomplete()
{
$this->complete(false);
}
}
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
REGISTRATION SYSTEM IN SECONDS
Create the login/registration system : php artisan make:auth
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
MIDDLEWARE
Middleware provide a convenient mechanism for filtering HTTP requests
entering your application.
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
MIDDLEWARE
Two types of middleware : Global Middleware, Assigning Middleware To
Routes
/**
* The application's route middleware.
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
MIDDLEWARE
Assign the route middleware in web.php
Route::resource('/projects', 'ProjectsController')->middleware('auth');
// Or can also create the middleware group
Route::group(['middleware' => ['auth']], function () {
Route::resource('/projects', 'ProjectsController');
Route::post('/projects/{project}/tasks', 'ProjectTasksController@store');
Route::patch('/tasks/{task}', 'ProjectTasksController@update');
});
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
AUTH FACADE
The auth () returns an authenticator instance.
You may use it instead of the Auth facade for convenience: Auth::user ()
auth()->id(); // User Id
auth()->user(); // User Instance
auth()->check(); // Boolean
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
AUTH FACADE
php artisan make:migration add_owner_id_to_projects --table=“projects”
Add this column owner_id & run this command : php artisan migrate:fresh
Schema::create('projects', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->text('description');
$table->timestamps();
});
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
VIEW OWN PROJECTS
Use the auth helper to view own projects
Chang the code in the ProjectsController.php
// List all projects
public function index()
{
$projects = Project::where('owner_id', auth()->id())->get();
return view('projects.index', compact('projects'));
}
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
VIEW OWN PROJECTS
Use the auth helper to view own projects
Chang the code in the ProjectsController.php
// Save the project
public function store(Project $project)
{
$project->create(
request()->validate([
'title' => 'required|min:3',
'description' => 'required|min:3',
]) + ['owner_id' => auth()->id()]
);
return redirect('/projects');
}
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
AUTHORIZATION ESSENTIALS
php artisan make:policy ProjectPolicy --model=Project
Write the condition for the ProjectPolicy.php & register in AuthServiceProvider
public function view(User $user, Project $project)
{
return $project->owner_id === $user->id;
}
public function update(User $user, Project $project)
{
return $project->owner_id === $user->id;
}
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
AUTHORIZATION ESSENTIALS
php artisan make:policy ProjectPolicy --model=Project
Write the condition for the ProjectPolicy.php & register in AuthServiceProvider
class AuthServiceProvider extends ServiceProvider
{
protected $policies = [
'App\ProjectPolicy' => 'App\Policies\ProjectPolicy',
];
...
}
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
AUTHORIZATION ESSENTIALS
Use the authroize () in ProjectsController.php
// Show the project
public function show(Project $project)
{
$this->authorize('view', $project);
...
}
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
AUTHORIZATION ESSENTIALS
Or Simplify the code in web.php
Route::resource('/projects', ‘ProjectsController')
->middleware('can:view, project');
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
ADMIN ACCESS EVERYTHING
Use the before () of Gate facade in AuthServiceProvider.php
public function boot()
{
...
Gate::before(function ($user) {
return $user->id == 1;
});
}
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
ADMIN ACCESS EVERYTHING
Use the before () of Gate facade in AuthServiceProvider.php
public function boot()
{
...
Gate::before(function ($user) {
return $user->id == 1;
});
}
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
DON’T REPEAT YOURSELF
Refactor the code validation process ProjectsController.php
Use this function in store() and update() as well
// Validate the project
protected function validateProject()
{
return request()->validate([
'title' => 'required|min:3',
'description' => 'required|min:3',
]);
}
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
API RESOURCES
Building API need a transformation layer between Eloquent models & JSON
responses
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
API RESOURCES
Generate the api resource: php artisan make:resource UserResource
class UserResource extends JsonResource
{
...
public function with($request)
{
return ['status' => 'success'];
}
public function withResponse($request, $response)
{
$response->setStatusCode(202);
}
}
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
API RESOURCES
Generate the api resource collections: php artisan make:resource
UserCollection
class UserCollection extends ResourceCollection
{
public function toArray($request)
{
return [
'data' => $this->collection,
'status' => 'success'
];
}
}
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
API RESOURCES
Add the new eloquent resource in api.php
namespace App\Http\Resources\ResourceName
Route::get('/users', function(){
$user = App\User::with('projects')->paginate(10);
return new UserCollection($user);
});
Route::get('/users/{id}', function($id){
$user = App\User::with('projects')->find($id);
return new UserResource($user);
});
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
API RESOURCES
Create a new user from api : php artisan make:request UserRequest
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Validation\ValidationException;
use Illuminate\Http\Exceptions\HttpResponseException;
public function rules()
{
return [
'name' => ['required', 'string', 'max:255', 'min:5'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:6', 'confirmed'],
];
}
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
API RESOURCES
Override the function to response the JSON format.
protected function failedValidation(Validator $validator)
{
$errors = (new ValidationException($validator))->errors();
throw new HttpResponseException(
response()->json([
'data' => [],
'errors' => $errors,
'success' => false,
'method' => request()->method()
], 400)
);
}
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
API RESOURCES
Add a new route and create a new user in api.php
Route::post('/users', function(UserRequest $request, User $user){
$attributes = $request->except(['password_confirmation']);
$attributes['password'] = Hash::make($request->password);
return new UserResource($user->create($attributes));
});
TEXT
LARAVEL FRAMEWORK FOR BUILDING WEB APP
CREATE PROJECTS API
Run the command : php artisan make:model Project
Goal: Create the Projects API in url api/projects
1. Insert
Createthe dataroute
the new via tinker : php artisan tinker
in `api.php’
2. Create ProjectsService controller via artisan command
3. Use the Project::all() in the controller
4. Pass the data of projects collection into JSON response
4. Test your work!
THANK
YOU !