Laravel Posts
How to use laravel multi tenant (stancl/tenancy) with single DB ?Laravel

How to use laravel multi tenant (stancl/tenancy) with single DB ?Laravel
Nowadays multi-tenant applications are more useful than single-tenant applications. We can use multi-tenant with multiple databases or single databases as per our need. But it's better to use a single DB with a multi-tenant when you have a small application.
In this tutorial, we are going to use multi-tenant with a single database.
We will implement multi-tenant with single DB by using the following package: https://github.com/archtechx/tenancy
Assuming you already have Laravel 8 repo setup. Now please follow the given steps to implement multi-tenancy with a single DB.
Package Installation
Run following commands :
-
composer require stancl/tenancy
-
php artisan tenancy:install
php artisan migrate
Add following service provider to config/app.php
App\Providers\TenancyServiceProvider::class
Create Custom Model
Now create modal named MultiTenant
into app\Models
MultiTenant.php
SavingTenant::class,
'saved' => TenantSaved::class,
'creating' => CreatingTenant::class,
// 'created' => TenantCreated::class,
'updating' => UpdatingTenant::class,
'updated' => TenantUpdated::class,
'deleting' => DeletingTenant::class,
'deleted' => TenantDeleted::class,
];
}
Update Tenancy Configuration
As we have added custom model we also need to define that model into config/tenancy.php
Please change tenant_model
value to our custom model.
'tenant_model' => \App\Models\MultiTenant::class,
Add Resolver
To use multi tenant with single DB we also need to add our customer resolver, that will be used into Middlewares that we will create ahead.
Create MultiTenantResolver
into app\Resolvers
App\Resolvers\MultiTenantResolver.php
find(Auth::user()->tenant_id)) {
return $tenant;
}
throw new TenantCouldNotBeIdentifiedByPathException($id);
}
public function getArgsForTenant(Tenant $tenant): array
{
return [
[$tenant->id],
];
}
}
Add Middleware
We will create our custom middleware that will set the current tenant into cache, and that will used by package to fire default query where('tenant_id', "tenant id we have set into middleware")
App\Http\Middleware\MultiTenantMiddleware.php
tenancy = $tenancy;
$this->resolver = $resolver;
}
/**
* Handle an incoming request.
*
* @param Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$tenant = Auth::user()->tenant_id;
return $this->initializeTenancy(
$request, $next, $tenant
);
}
}
Also, don't forget to add middleware alias into App\Http\kernel.php
protected $routeMiddleware = [
..............
'multi_tenant' => MultiTenantMiddleware::class,
];
Now we will apply this multi_tenant
middleware to our routes.
Add Trait to tenant-specific models
We have to add BelongsToTenant
trait to all of our tenant-specific models.
Say if we want to add tenant_id
into the users table then we must have to add BelongsToTenant
to the app\Models\User
model.
That trait will by default add following query everytime when we will try to fetch records or update records.
Where('tenant_id', 'tenant id will taken from cache')
Add tenant_id to tenant-specific migrations
As we have added the tenant trait, we must have to add tenant_id
into tenant-specific migrations as specified below.
public function up()
{
Schema::create('users', function (Blueprint $table) {
...........................
$table->string('tenant_id');
$table->foreign('tenant_id')
->references('id')
->on('tenants')
->onUpdate('cascade')
->onDelete('cascade');
$table->timestamps();
});
Update TenancyServiceProvider
Replace the App\Providers\TenactServiceProvider
by the following code.
[],
Events\TenantCreated::class => [
JobPipeline::make([
Jobs\CreateDatabase::class,
Jobs\MigrateDatabase::class,
// Jobs\SeedDatabase::class,
// Your own jobs to prepare the tenant.
// Provision API keys, create S3 buckets, anything you want!
])->send(function (Events\TenantCreated $event) {
return $event->tenant;
})->shouldBeQueued(false), // `false` by default, but you probably want to make this `true` for production.
],
Events\SavingTenant::class => [],
Events\TenantSaved::class => [],
Events\UpdatingTenant::class => [],
Events\TenantUpdated::class => [],
Events\DeletingTenant::class => [],
Events\TenantDeleted::class => [
JobPipeline::make([
Jobs\DeleteDatabase::class,
])->send(function (Events\TenantDeleted $event) {
return $event->tenant;
})->shouldBeQueued(false), // `false` by default, but you probably want to make this `true` for production.
],
// Domain events
Events\CreatingDomain::class => [],
Events\DomainCreated::class => [],
Events\SavingDomain::class => [],
Events\DomainSaved::class => [],
Events\UpdatingDomain::class => [],
Events\DomainUpdated::class => [],
Events\DeletingDomain::class => [],
Events\DomainDeleted::class => [],
// Database events
Events\DatabaseCreated::class => [],
Events\DatabaseMigrated::class => [],
Events\DatabaseSeeded::class => [],
Events\DatabaseRolledBack::class => [],
Events\DatabaseDeleted::class => [],
// Tenancy events
Events\InitializingTenancy::class => [],
Events\TenancyInitialized::class => [
// Listeners\BootstrapTenancy::class,
],
Events\EndingTenancy::class => [],
Events\TenancyEnded::class => [
Listeners\RevertToCentralContext::class,
],
Events\BootstrappingTenancy::class => [],
Events\TenancyBootstrapped::class => [],
Events\RevertingToCentralContext::class => [],
Events\RevertedToCentralContext::class => [],
// Resource syncing
Events\SyncedResourceSaved::class => [
Listeners\UpdateSyncedResource::class,
],
// Fired only when a synced resource is changed in a different DB than the origin DB (to avoid infinite loops)
Events\SyncedResourceChangedInForeignDatabase::class => [],
];
}
public function register()
{
//
}
public function boot()
{
$this->bootEvents();
// $this->mapRoutes();
$this->makeTenancyMiddlewareHighestPriority();
}
protected function bootEvents()
{
foreach ($this->events() as $event => $listeners) {
foreach (array_unique($listeners) as $listener) {
if ($listener instanceof JobPipeline) {
$listener = $listener->toListener();
}
Event::listen($event, $listener);
}
}
}
protected function mapRoutes()
{
if (file_exists(base_path('routes/tenant.php'))) {
Route::namespace(static::$controllerNamespace)
->group(base_path('routes/tenant.php'));
}
}
protected function makeTenancyMiddlewareHighestPriority()
{
$tenancyMiddleware = [
// Even higher priority than the initialization middleware
Middleware\PreventAccessFromCentralDomains::class,
Middleware\InitializeTenancyByDomain::class,
Middleware\InitializeTenancyBySubdomain::class,
Middleware\InitializeTenancyByDomainOrSubdomain::class,
Middleware\InitializeTenancyByPath::class,
Middleware\InitializeTenancyByRequestData::class,
];
foreach (array_reverse($tenancyMiddleware) as $middleware) {
$this->app[\Illuminate\Contracts\Http\Kernel::class]->prependToMiddlewarePriority($middleware);
}
}
}
Create / Fetch Tenant
Now we have to create a tenant and give that tenant_id to related users.
each user contains their specific tenant_id.
Use the following code to create a tenant :
$tenant1 = \App\Models\MultiTenant::create([
'name' => 'Tenant 1'
]);
$tenant2 = \App\Models\MultiTenant::create([
'name' => 'Tenant 2'
]);
That will create tenant into tenants
table and values will be stored into data
column as a son.
$tenant1 = App\Models\MultiTenant::where('data->name', 'Tenant 1')->first();
$tenant2 = App\Models\MultiTenant::where('data->name', 'Tenant 2')->first();
$tenant1User = User::where('id', 'user id here')->update(['tenant_id' => $tenant1->id]);
$tenant2User = User::where('id', 'user id here')->update(['tenant_id' => $tenant2->id]);
Now we have 2 tenants with 2 separate users who contain separate tenant ids.
Add Middleware to Routes
Now do login with User 1 and try to fetch all users from the database, it will return users of logged-in users' tenants only.
As we have the BelongToTenant
trait into the User
model.
Route::group(['middleware' => ['auth', 'multi_tenant']], function () { Route::get('users', function() {
// only tenant-1 users will be returned because we are setting the logged-in user tenant into the cache from `multi_tenant`middleware.
$allUsers = User::all();
});
});
You can use the same for other models too.
Hope this helps you.
How to setup React in LaravelLaravel

How to setup React in LaravelLaravel
In this article, I show you how to set up react application in Laravel Framework. as you know react is a very flexible frontend library and works with together any backend framework, so let start and follow the following steps. I hope you have created the laravel application.
You can watch the following video tutorial or follow this article as well,
Step 1:
Let's go to the resource directory in laravel. now let's create react application. you should watch the following tutorial if you don't know how to create react application.
Step 2:
Merge the package.json
and package-lock.json
files in the root. fire npm install && npm run dev
command in terminal for compile react application to js.
Step 3:
In this step, you need to set up a webpack.mix.js
file. put the following code in the webpack.mix.js
file.
mix.options({
postCss: [
require('autoprefixer'),
],
});
mix.setPublicPath('public');
mix.webpackConfig({
resolve: {
extensions: ['.js', '.vue'],
alias: {
'@': __dirname + 'resources'
}
},
output: {
chunkFilename: 'js/chunks/[name].js',
},
}).react();
// used to run app using reactjs
mix.js('resources/react-app/src/index.js', 'public/js/app.js').version();
mix.copy('resources/react-app/public', 'public');
NOTE: Don't forget to change the index.js path based on your application name
Step 4:
Let's add <div id="root"></div>
to your application's root blade file
Step 5:
Let's inlude <script type="text/javascript" src="{{ mix('js/app.js') }}"></script>
to your application's root blade file before end the body tag.
So, the Basic setup is done. enjoy react with laravel.
How to generate User Device API using Laravel One SignalLaravel

How to generate User Device API using Laravel One SignalLaravel
Generally, we are using a Laravel One Signal package for push notification. if you are planning to use one signal in the mobile application then this package right for you.
Recently, I add a new feature UserDevice. let me explain why I added support for user Device APIs.
We need to create an API to register a device because One Signal sends a push notification using os player id. so, we need to store os_player_id in the backend from the mobile application. So, need to create an API for it.
Now. you can save your time using this package. you can Generate APIs using one artisan command,
php artisan one-signal.userDevice:publish
This command generates the following files,
- UserDeviceAPIController
- UserDeviceAPIRepository
- UserDevice (model)
- Migration So, everything is ready in minutes and delivered an API on the spot.
Also, do not forget to add the following routes to the api.php file.
use App\Http\Controllers\API\UserDeviceAPIController;
Route::post('user-device/register', [UserDeviceAPIController::class, 'registerDevice']);
Route::get('user-device/{playerId}/update-status', [UserDeviceAPIController::class, 'updateNotificationStatus'])
How to generate pre-signed URL from s3 bucket ?Laravel

How to generate pre-signed URL from s3 bucket ?Laravel
People nowadays are becoming more intelligent, so better to protect our application's content/data from those who are calling themself hackers.
One of the best examples is the data URLs from AWS buckets. it's not a good idea to store sensitive data into a public AWS Bucket, as the URL is accessible by the people.
Of Course, you can store profile avatars and others data to the public bucket's that not contains any confidential information. so that's fine.
But when it's about confidential information like PAN CARD Details, AADHAR Card Details, Bank Informations we Must Recommend using AWS Protected Bucket.
In this tutorial, we are going to show that how we can prevent that kind of case, Or how we can integrate AWS Protected Bucket in our Laravel Application.
The following code will help you to generate a pre-signed AWS URL that will prevent our data, that URL is non-guessable and it will expire within some minutes/hours specified by us.
So let's start with some code :
$s3 = \Storage::disk(config('filesystems.s3_protected_disk'));
$client = $s3->getDriver()->getAdapter()->getClient();
$expiry = "+1 minutes";
$command = $client->getCommand('GetObject', [
'Bucket' => \Config::get('filesystems.disks. s3_protected_disk.bucket'),
'Key' => 'Path to your file',
]);
$request = $client->createPresignedRequest($command, $expiry);
return (string) $request->getUrl();
So here we have created an s3 instance and it's stored on the $s3 variable, we have specified the expiry time as 1 minute so the given URL for data will be expired within a minute.
Also, we have to specify the bucket name and path to our protected file to generate AWS pre-signed URL.
It will return the pre-signed URL and its looks like as the following URL.
https://pre-signed.s3.au-west-2.amazonaws.com/image.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=xxxxxxxx%2F20180210%2Feu-west-2%2Fs3%2Faws4_request&X-Amz-Date=20210210T171315Z&X-Amz-Expires=60&X-Amz-Signature=xxxxxxxx&X-Amz-SignedHeaders=host
Hope this helps.
How to display responsive image in different devicesLaravel

How to display responsive image in different devicesLaravel
Today we are going to see how we can image based on resolution. We have the most common issue of loading big images in small devices take time. So, the basic solution is to use the picture element to load a different image in different devices and resolutions.
The <picture>
element will be for the art direction of responsive design.
The element contains two tags.
<source>
<img>
So, the browser will look for the first <source>
element where the media query matches the current width, and then it will display the image. The <picture>
element is required as the last child of the <picture>
element.
Let me show you an example of how to display a different image in different widths.
Here is a Code example,
<picture>
<source media="(min-width:900px)" srcset="infyom_logo_lg.jpg">
<source media="(min-width:700px)" srcset="infyom_logo_md.jpg">
<source media="(min-width:500px)" srcset="infyom_logo_sm.jpg">
<img src="infyom_logo_xl.jpg" alt="Flowers" style="width:auto;">
</picture>
How to setup passwordless Login In LaravelLaravel

How to setup passwordless Login In LaravelLaravel
Basically, we set up email/username and password login in all our projects. but, sometimes we need to implement s passwordless login in the laravel application,
First of all, what is passwordless login? passwordless login is an authentication method that allows the user to log in without entering a password.
In this article, I show you how to set up passwordless login laravel step by step.
Step 1:
one great laravel package Laravel Passwordless Login provides the ability to log in without a password.
This package provides a temporary signed URL link that logs in a user, What it does not provide is a way of actually sending the link to the route to the user. This is because I don't want to make any assumptions about how you communicate with your users.
Step 2:
Open the terminal and go to the project directory and fire the following command to install
composer require grosv/laravel-passwordless-login
Step 3:
Configure the following variables in your env file
LPL_USER_MODEL=App\User
LPL_REMEMBER_LOGIN=false
LPL_LOGIN_ROUTE=/magic-login
LPL_LOGIN_ROUTE_NAME=magic-login
LPL_LOGIN_ROUTE_EXPIRES=30
LPL_REDIRECT_ON_LOGIN=/
LPL_USER_GUARD=web
LPL_USE_ONCE=false
LPL_INVALID_SIGNATURE_MESSAGE="Expired or Invalid Link"
Step 4:
Create one function in your login controller. it looks like
use App\User;
use Grosv\LaravelPasswordlessLogin\LoginUrl;
function sendLoginLink(\Request $request)
{
$user = User::where('email','=', $request->get('email))->first();
$generator = new LoginUrl($user);
$url = $generator->generate();
//OR Use a Facade
$url = PasswordlessLogin::forUser($user)->generate();
$data['url'] = $generator->generate();
$data['user'] = $user;
Mail::to($user->email)->send(new UserLoginMail($data));
return back();
}
Step 5:
Set following route in your web.php
Route::post('/user/login', [LoginController::class, 'sendLoginLink'])->name('userLogin');
Step 6:
Create one mailable. you can refer to a doc if not familiar. Also, fire the following command to create a mailable
php artisan make:mail UserLoginMail
Step 7: Create an Email UI as per your requirement.
How to Setup Global Git Ignore in windowLaravel

How to Setup Global Git Ignore in windowLaravel
Lots of developers have a question: How do I create a global gitignore file? so, In this article, I show how to set up a global git ignore.
Reviewing pull requests, I often see contributors sneakily adding editor configuration to the repository’s .gitignore file.
If everyone would commit their environment-specific .gitignore rules, we’d have a long list to maintain! My repository doesn’t care about your editor configuration.
There’s a better solution to this: a personal, global .gitignore file for all your repositories. Here’s how you can set one up. create a .gitignore file for your global rules.
You can also see the following video tutorial as well.
You need to set up your global core.excludesfile configuration file to point to this global ignore file. So, let's start step by step
Step 1:
Create a file .gitignore on your profile C:\Users{username} for example C:\Users\Shailesh
Step 2:
Now you can set a .gitignore path with a three-way. we need to tell this to get this my global git to ignore file.
First Way: Using Windows git bash
Let's open Windows git bash and fire the following command,
git config --global core.excludesFile '~/.gitignore'
Second Way: Using Windows cmd
Let's open Windows cmd and fire the following command,
git config --global core.excludesFile "%USERPROFILE%\.gitignore"
Third Way: Using Windows PowerShell
Let's open Windows PowerShell and fire the following command,
git config --global core.excludesFile "$Env:USERPROFILE\.gitignore"
So, you can easily set the .gitignore global file.
How to develop package into Laravel ?Laravel

How to develop package into Laravel ?Laravel
In our daily life, we are going through lots of packages, and some of us don't know how to build our own package into Laravel.
We are going to perform the core steps to create your own package in laravel. In this tutorial we are going to build a zoom package, so we will perform steps related to it.
Setup Fresh Laravel Repo
Setup fresh laravel repo, and then create directories within it.
for e.g Create infyomlabs/zoom-api directory into the root.
Now create src directory into zoom-api
Run Composer init Into src Directory
After hitting composer init it will ask for some information from you, as you can see below image I have entered some of the information. you can just hit enter if you do not want to add other information.
Add your config file (Optional)
Create a directory config into the src directory and add your config.php file there from where you can manage your env variables.
Add Service Provider
Create your service provider from where you can do lots of actions. like you can publish config/routes/ migrations files from there. Here we are publishing the zoom config file.
Add your class (Which contains all functions)
Here we have added a Zoom class which will contain all zoom functions.
Update Composer.json
Finally, Test it in your existing project
Put the following code to your main composer.json (in your project's root). and hit composer update
"repositories": [
{
"type": "path",
"url": "infyomlabs/zoom-api",
"options": {
"symlink": true
}
}
],
"license": "MIT",
"require": {
"infyomlabs/zoom-api": "dev-develop"
},