Tuesday, September 28, 2021

laravel 8 data_fill

 $data = [

    'products' => [

        ['name' => 'Desk 1', 'price' => 100],

        ['name' => 'Desk 2'],

    ],

];


data_fill($data, 'products.*.price', 200);


/*

    [

        'products' => [

            ['name' => 'Desk 1', 'price' => 100],

            ['name' => 'Desk 2', 'price' => 200],

        ],

    ]

*/

laravel difference between fill and update

<?php

$user = User::find(1);

// This will update immediately

$user->update(['first_name' => 'Braj', 'last_name' => 'Mohan']);


//But what if you do not want to update immediately. Suppose you also want to make user active before the actual update. Then fill method comes handy.

$user = User::find(1);

// This will not update underlying data store immediately

$user->fill(['first_name' => 'Braj', 'last_name' => 'Mohan']);

// At this point user object is still only in memory with updated values but actual update query is not performed.

// so we can have more logic here 

$user->is_active = true;

// Then finally we can save it.

$user->save(); // This will also make user active


//Update method is dumb and makes the query to database even if no values are changed. But save method is intelligent and calculates if you really changed anything and do not perform query if nothing has changed for example.


$user = User::find(1);

//suppose user object has following values after fetching

// first_name = 'Braj';

// second_name = 'Mohan';

// is_active = true;

// Then if you set the values like following without any change

$user->is_active = true; // it is already true so no change

$user->save(); // this won't perform any database query hence is efficient

Sunday, September 19, 2021

Laravel Multiple Database Connections Example

Hello Artisan

In this tutorial we will discuss about laravel multiple database connections. Do you know how to connect laravel multiple database connections? If you don't know then you are right place. In this tutorial i will show you step by step that multiple db connection in laravel 7/6.

You know that sometime we need to setup multiple database connection like mysql, mongodb etc. i can say when you work with large amount of project then you will need maybe. So let's follow bellow step to learn multiple database connection in laravel 7/6.

I will add configuration variable on .env file and use it to database configuration file. You can just follow this laravel 7/6 multiple database connections tutorial, i will also teach how to work with migration, model and database query for multiple database connection.

You have to set configuration variable on .env file. do it.

.env

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=mydatabase
DB_USERNAME=root
DB_PASSWORD=root

DB_CONNECTION_SECOND=mysql
DB_HOST_SECOND=127.0.0.1
DB_PORT_SECOND=3306
DB_DATABASE_SECOND=mydatabase2
DB_USERNAME_SECOND=root
DB_PASSWORD_SECOND=root
PHP

 

Now, as i created variable in .env file, we need to use that variable on config/database.php file so let's open database.php file and add new connections key as like bellow:

config/database.php

use Illuminate\Support\Str;
  
return [
   
    'default' => env('DB_CONNECTION', 'mysql'),
   
    'connections' => [
        .....
   
        'mysql' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],
        'mysql2' => [
            'driver' => env('DB_CONNECTION_SECOND'),
            'host' => env('DB_HOST_SECOND', '127.0.0.1'),
            'port' => env('DB_PORT_SECOND', '3306'),
            'database' => env('DB_DATABASE_SECOND', 'forge'),
            'username' => env('DB_USERNAME_SECOND', 'forge'),
            'password' => env('DB_PASSWORD_SECOND', ''),
            'unix_socket' => '',
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
        ],
PHP

 

Here, i will give you simple example of how we can use as multiple connection to create migration. So to create migration just add which connection are you going to use.

public function up()
{
    Schema::connection('mysql2')->create('blog', function (Blueprint $table) {
        $table->increments('id');
        $table->string('title');
        $table->string('body')->nullable();
        $table->timestamps();
    });
}
PHP

 

Now we need to setup every model as like below before working with database.

namespace App;
  
use Illuminate\Database\Eloquent\Model;
   
class Blog extends Model
{
    protected $connection = 'mysql2';
}
PHP

 

Now we have to user controller method as like below

class BlogController extends BaseController
{
    public function getRecord()
    {
        $blogModel = new Blog;
        $blogModel->setConnection('mysql2');
        $find = $blogModel->find(1);
        return $find;
    }
}
PHP

 

If you need to use query builder, then just follow and use this method.

$blogs = DB::table("blog")->get();
print_r($blogs);
   
$blogs = DB::connection('mysql2')->table("blog")->get(); 

print_r($blogs); 


Laravel 8 Login with Custom Guard Auth Example

Hello Artisan

In this tutorial i will discuss about Laravel custom login with custom guard. To create this laravel multiple guards authentication setup and login i will use doctors table without user model. We know that Laravel uses User model to create default authentication.

So in this laravel custom guard tutorial we will see how we can setup and create our custom guard and make a custom login and logout system in Laravel. Having finished this Laravel custom guard tutorial you will be able to make laravel multi auth in your application.

Laravel uses web as default guard and auth uses as default auth middleware to check whether a user is logged in or not. We will use our own guard to define custom guard name and will create a custom login and logout system with this guard.

So let's see how we can create login system using guard. I have already created this tutorial for Laravel 5. You can see that. In that tutorial i used User model. So you can read also.

 

Read also : Laravel Multi Auth | Multiple Authentication in Laravel 

 

laravel-8-login-with-custom-guard-example

App\Model\Doctor.php

namespace App\Models;

use Illuminate\Support\Facades\Hash;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;

class Doctor extends Authenticatable
{
    use HasFactory, Notifiable;
    
    protected $guarded = [];

    public function setPasswordAttribute($value)
    {
        $this->attributes['password'] = Hash::make($value);
    }

    public function scopeIsActive($query)
    {
        return $query->where('is_active',1);
    }
}
PHP

 

And in migrations file, paste this below code.

public function up()
{
  Schema::create('doctors', function (Blueprint $table) {
      $table->id();
      $table->string('name');
      $table->string('email',32)->unique();
      $table->string('password',255);
      $table->boolean('is_active')->default(true);
      $table->timestamps();
  });
}
PHP

 

Step 3 : Setup or Create Custom Guard

 

In this step we need to create our custom guard name. So visit config/auth.php and create your own guard name as many as you want.

config/auth.php

return [

    /*
    |--------------------------------------------------------------------------
    | Authentication Defaults
    |--------------------------------------------------------------------------
    |
    | This option controls the default authentication "guard" and password
    | reset options for your application. You may change these defaults
    | as required, but they're a perfect start for most applications.
    |
    */

    'defaults' => [
        'guard' => 'web',
        'passwords' => 'users',
    ],

    /*
    |--------------------------------------------------------------------------
    | Authentication Guards
    |--------------------------------------------------------------------------
    |
    | Next, you may define every authentication guard for your application.
    | Of course, a great default configuration has been defined for you
    | here which uses session storage and the Eloquent user provider.
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | Supported: "session", "token"
    |
    */

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'doctor' => [
            'driver' => 'session',
            'provider' => 'doctors',
        ],

        'api' => [
            'driver' => 'token',
            'provider' => 'users',
            'hash' => false,
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | User Providers
    |--------------------------------------------------------------------------
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | If you have multiple user tables or models you may configure multiple
    | sources which represent each model / table. These sources may then
    | be assigned to any extra authentication guards you have defined.
    |
    | Supported: "database", "eloquent"
    |
    */

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\User::class,
        ],
        'doctors' => [
            'driver' => 'eloquent',
            'model' => App\Models\Doctor::class,
        ],

        // 'users' => [
        //     'driver' => 'database',
        //     'table' => 'users',
        // ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Resetting Passwords
    |--------------------------------------------------------------------------
    |
    | You may specify multiple password reset configurations if you have more
    | than one user table or model in the application and you want to have
    | separate password reset settings based on the specific user types.
    |
    | The expire time is the number of minutes that the reset token should be
    | considered valid. This security feature keeps tokens short-lived so
    | they have less time to be guessed. You may change this as needed.
    |
    */

    'passwords' => [
        'users' => [
            'provider' => 'users',
            'table' => 'password_resets',
            'expire' => 60,
            'throttle' => 60,
        ],
        'doctors' => [
            'provider' => 'doctors',
            'table' => 'password_resets',
            'expire' => 60,
            'throttle' => 60,
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Password Confirmation Timeout
    |--------------------------------------------------------------------------
    |
    | Here you may define the amount of seconds before a password confirmation
    | times out and the user is prompted to re-enter their password via the
    | confirmation screen. By default, the timeout lasts for three hours.
    |
    */

    'password_timeout' => 10800,

];
PHP

 

Step 4:  Create Route

 

Now in this step we have to create our route for create Laravel multi auth using guard. Let's create our route.

routes/doctor.php

use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Doctor\Auth\LoginController;


Route::name('doctor.')->namespace('Doctor')->prefix('doctor')->group(function(){

    Route::namespace('Auth')->middleware('guest:doctor')->group(function(){
        //login route
        Route::get('/login','LoginController@login')->name('login');
        Route::post('/login','LoginController@processLogin');
    });

    Route::namespace('Auth')->middleware('auth:doctor')->group(function(){

        Route::post('/logout',function(){
            Auth::guard('doctor')->logout();
            return redirect()->action([
                LoginController::class,
                'login'
            ]);
        })->name('logout');

    });

});
PHP

 

Now we have to define our custom route path from route service provider. So change it like below.

namespace App\Providers;

use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Route;

class RouteServiceProvider extends ServiceProvider
{
 
    public const HOME = '/home';

    public const DOCTOR = '/doctor/home';

    protected $namespace = 'App\\Http\\Controllers';

    public function boot()
    {
        $this->configureRateLimiting();

        $this->routes(function () {
            Route::prefix('api')
                ->middleware('api')
                ->namespace($this->namespace)
                ->group(base_path('routes/api.php'));

            Route::middleware('web')
                ->namespace($this->namespace)
                ->group(base_path('routes/web.php'));

           //our custom route path
            Route::middleware('web')
                ->namespace($this->namespace)
                ->group(base_path('routes/doctor.php'));
        });
    }

    protected function configureRateLimiting()
    {
        RateLimiter::for('api', function (Request $request) {
            return Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip());
        });
    }
}
PHP

 

Step 5: Create Controller

Now in this step you have to create our login controller and method which are defined in doctor.php route. So let's create those method.

App\Http\Controllers\Doctor\Auth\LoginController.php

namespace App\Http\Controllers\Doctor\Auth;

use Illuminate\Http\Request;
use Facades\App\Helper\Helper;
use App\Http\Requests\LoginRequest;
use App\Http\Controllers\Controller;
use App\Models\Doctor;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\View;
use App\Providers\RouteServiceProvider;
use Symfony\Component\HttpFoundation\Response;

class LoginController extends Controller
{   
    public function login()
    {
        if(View::exists('doctor.auth.login'))
        {
            return view('doctor.auth.login');
        }
        abort(Response::HTTP_NOT_FOUND);
    }

    public function processLogin(Request $request)
    {   
        $credentials = $request->except(['_token']);
        
        if(isDoctorActive($request->email))
        {
            if(Auth::guard('doctor')->attempt($credentials))
            {   
                return redirect(RouteServiceProvider::DOCTOR);
            }
            return redirect()->action([
                LoginController::class,
                'login'
            ])->with('message','Credentials not matced in our records!');
        }
        return redirect()->action([
            LoginController::class,
            'login'
        ])->with('message','You are not an active doctors!');
    }
}
PHP

 

Now paste this in your helper.php file.

app\helper.php

use App\Models\Doctor;

if(!function_exists('isDoctorActive'))
{
    function isDoctorActive($email) : bool
    {   
        $doctor = Doctor::whereEmail($email)->IsActive()->exists();

        if($doctor)
        {
            return true;
        }
        return false;
    }
}
PHP

 

Now almost all are set to. We have to just create our blade view. 

Step 6: Create Blade

Now just paste this html code in this following path to create login system in Laravel using custom guard.

resources/views/doctor/auth/login.blade.php


@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Doctor Login') }}</div>
                @if(session()->has('message'))
                    <span>{{ session()->get('message') }}</span>
                @endif
                <div class="card-body">
                    <form method="POST" action="{{ route('doctor.login') }}">
                        @csrf

                        <div class="form-group row">
                            <label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>

                            <div class="col-md-6">
                                <input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>

                                @error('email')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="form-group row">
                            <label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>

                            <div class="col-md-6">
                                <input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">

                                @error('password')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="form-group row">
                            <div class="col-md-6 offset-md-4">
                                <div class="form-check">
                                    <input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>

                                    <label class="form-check-label" for="remember">
                                        {{ __('Remember Me') }}
                                    </label>
                                </div>
                            </div>
                        </div>

                        <div class="form-group row mb-0">
                            <div class="col-md-8 offset-md-4">
                                <button type="submit" class="btn btn-primary">
                                    {{ __('Login') }}
                                </button>

                                @if (Route::has('password.request'))
                                    <a class="btn btn-link" href="{{ route('password.request') }}">
                                        {{ __('Forgot Your Password?') }}
                                    </a>
                                @endif
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection
 
HTML

 

for logout, use this route and form


<a class="dropdown-item" href="{{ route('doctor.logout') }}" onclick="event.preventDefault();
  document.getElementById('logout-form').submit();">
  {{ __('Logout') }}
</a>

<form id="logout-form" action="{{ route('doctor.logout') }}" method="POST" class="d-none">
   @csrf
</form> 
HTML

 

Hope you have understand this example tutorial. You can create as many guard as you want from config/auth.php and have to make login system using those custom guard. You can use User model or you can use other model. It doesn't matter.


Link: https://www.codecheef.org/article/laravel-8-login-with-custom-guard-example