Search code examples
phplaravelcart

Transfer shopping cart from guest to user logged?


I use https://github.com/darryldecode/laravelshoppingcart

I only have authentication by username without password

The problem is the sessions When I am a guest, the session code is for example

9ot0CjCYUQpYR10ox43A9GoHVp6vliXuFFsoZlGU

After registration it is renewed to a different code

HXTc6LXNEW79QzvrvnKwi2N3IBQWwSroBfghOznR

in config/auth.php

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

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => Modules\User\Entities\User::class,
        ],

        'customers' => [
            'driver' => 'eloquent',
            'model' => Modules\User\Entities\Customer::class,
        ],
    ],

CACHE_DRIVER=redis

SESSION_DRIVER=redis

in User/Http/Controllers/AuthController.php

public function verify(VerifyCodeRequest $request)
{
    $customer = $this->customer($request);
    /* code etc. */

    if ($customer->exists) {
     auth()->login($customer,true);
    }
}

in Cart/Providers/CartServiceProvider.php

    public function register()
    {
        $this->app->singleton(Cart::class, function ($app) {
            return new Cart(
                $app['session'],
                $app['events'],
                'cart',
                session()->getId(),
                config('fleetcart.modules.cart.config')
            );
        }); 
}

Solution

  • What worked for me (original code by @liamjcooper) was creating event listeners.

    namespace App\Providers;
    
    class EventServiceProvider extends ServiceProvider
    {
        /**
         * The event listener mappings for the application.
         *
         * @var array
         */
        protected $listen = [
            /* flash cart items */
            \Illuminate\Auth\Events\Attempting::class => [
                \App\Listeners\PrepareCartTransfer::class
            ],
            /* add flashed cart items to authenticated user cart */
            \Illuminate\Auth\Events\Login::class => [
                \App\Listeners\TransferGuestCartToUser::class
            ]
            /* end cart item */
        ];
    

    then ran

    php artisan event:generate
    

    at the listeners

    flash the cart content from guest

    namespace App\Listeners;
    
        class PrepareCartTransfer
        
        public function handle(Attempting $event)
        {
            if (Auth::guest()) {
                session()->flash('guest_cart', [
                    'session' => session()->getId(),
                    'data' => \Cart::getContent() 
                ]);
            }
        }
    

    transfer cart items to authenticated user

    namespace App\Listeners;
    
        class TransferGuestCartToUser
        {
            public function handle(Login $event)
            {
            $userCart = \Cart::getContent();
            $userCartItems = $userCart->toArray();
    
            if (session('guest_cart.data') != null ) {
                $guestCart = session('guest_cart.data');
                $guestCartItems = $guestCart->toArray();
            }
    
            if ($userCart->isNotEmpty() && !empty($guestCartItems)) {
                $maxUserCartId = max(array_column($userCartItems, 'id'));
    
                $guestCartItems = array_map(function ($item) use (&$maxUserCartId) {
                    return array_merge($item, ['id' => ++$maxUserCartId]);
                }, $guestCartItems);
            }   
    

    That did enough to me running stock package.