Keep the basket between logins

Help for integrating the Laravel package
Forum rules
Always add your Laravel, Aimeos and PHP version as well as your environment (Linux/Mac/Win)
Spam and unrelated posts will be removed immediately!
jafo66
Posts: 65
Joined: 06 Mar 2024, 04:42

Keep the basket between logins

Post by jafo66 » 29 Jul 2024, 02:34

Background:
I'm looking to have the basket be permanent or at least last from one login to another for a specified period of time. Right now I see a number of baskets created in the mshop_order_basket table from what I can understand from the code corresponds to the CSRF tokens but they change as you create a new session even if it is in the same browser as before.

Request: Can I have a cookie and then load the basket via the cookie value OR is there some setting in Aimeos that already handles this kind of situation?

Thanks!

User avatar
aimeos
Administrator
Posts: 8238
Joined: 01 Jan 1970, 00:00

Re: Keep the basket between logins

Post by aimeos » 30 Jul 2024, 08:43

This isn't supported at the moment. The easiest way to implement that is to load the last basket of the customer from the mshop_order_basket table after a successful login in the Laravel controller.
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, Image give us a star

jafo66
Posts: 65
Joined: 06 Mar 2024, 04:42

Re: Keep the basket between logins

Post by jafo66 » 01 Aug 2024, 06:48

Okay, that makes sense, but how do I "load" it? Do I use the basket ID column to load it and should that be with the "frontend" controller? Also, do I need to load it and then immediately save it so the session knows this is the one to use?

Thanks!

User avatar
aimeos
Administrator
Posts: 8238
Joined: 01 Jan 1970, 00:00

Re: Keep the basket between logins

Post by aimeos » 02 Aug 2024, 20:19

Search for the item with the user ID of the authenticated user and the latest mtime to get the last basket.

For using the basket, you currently need to copy the content from the old basket to the new basket. A better way in the future would be to add a method here that stores the old basket with the current ID:
https://github.com/aimeos/aimeos-core/b ... ession.php
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, Image give us a star

jafo66
Posts: 65
Joined: 06 Mar 2024, 04:42

Re: Keep the basket between logins

Post by jafo66 » 05 Aug 2024, 03:44

Could I use the "named basket" functionality behind the scenes? Meaning, I looked for a basket named "MySpecialBaskets", if found load it, save it, and the delete the older one with the same name?

One note on this question... I have already hidden the named baskets functionality from the user for other reasons.

User avatar
aimeos
Administrator
Posts: 8238
Joined: 01 Jan 1970, 00:00

Re: Keep the basket between logins

Post by aimeos » 08 Aug 2024, 08:14

jafo66 wrote: 05 Aug 2024, 03:44 Could I use the "named basket" functionality behind the scenes? Meaning, I looked for a basket named "MySpecialBaskets", if found load it, save it, and the delete the older one with the same name?
If named or not, they are all stored baskets. You only have to get the one with the latest modification time and push it's content into the current basket.
jafo66 wrote: 05 Aug 2024, 03:44 One note on this question... I have already hidden the named baskets functionality from the user for other reasons.
That's no problem.
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, Image give us a star

jafo66
Posts: 65
Joined: 06 Mar 2024, 04:42

Re: Keep the basket between logins

Post by jafo66 » 25 Sep 2024, 06:42

So I built this listener:

Code: Select all

<?php

namespace App\Listeners;

use Illuminate\Support\Facades\Log;
use Illuminate\Auth\Events\Login;

class LoginListener
{
    /**
     * Create the event listener.
     */
    public function __construct()
    {
        Log::debug('LoginListener.constructor - starting');
    }

    /**
     * Handle the event.
     */
    public function handle(Login $event): void
    {
        //Log::debug('LoginListener.handle() - event received: ' . print_r($event, true));
        $context = app('aimeos.context')->get(true);
        $controller = new \Aimeos\Controller\Frontend\Basket\Standard($context);
        $userId = $event->user['id'];
        $sql = "
            select id, content 
            from mshop_order_basket
            where customerid = ?
            and mtime = (
                select max(mtime) from mshop_order_basket where customerid = ?
            )        
        ";
        $results = $context->db()->query($sql, [$userId, $userId])->all();
        if (count($results) > 0) {
            foreach ($results as $item) {
                Log::debug('LoginListener.handle() - found this basket id to load: ' . $item['id']);
                $oldbasket = $controller->load($item['id']);
                $basket = $controller->get()->setCustomerId($context->user());
                $basket->setProducts($oldbasket->getProducts()->toArray());
                $controller->save();
            }
        }
        else {
            Log::info('LoginListener.handle() - no baskets to load');
        }
    }
}

However, the load fails indicating it was looking for an "order.id". In the mshop_order_basket table there is the contents, so I'm not sure how to load the "old" basket into the current basket. Can you tell me where I'm going wrong?

jafo66
Posts: 65
Joined: 06 Mar 2024, 04:42

Re: Keep the basket between logins

Post by jafo66 » 25 Sep 2024, 07:04

I was able to figure it out with this updated code:

Code: Select all

        $results = $context->db()->query($sql, [$userId, $userId])->all();
        if (count($results) > 0) {
            foreach ($results as $item) {
                Log::debug('LoginListener.handle() - found this basket id to load: ' . $item['id']);
                if (($order = \Aimeos\MShop::create($context, 'order/basket')->get($item['id'])->getItem()) !== null) {
                    $basket = $controller->get()->setCustomerId($context->user());
                    $basket->setProducts($order->getProducts()->toArray());
                    $controller->save();                    
                }
            }
        }
        else {
            Log::info('LoginListener.handle() - no baskets to load');
        }
The listener works properly now. My question right now is the login event is happening at the same time as the Vue page being rendered. Is there a way insert this logic at the time of login instead in parallel to the login?

User avatar
aimeos
Administrator
Posts: 8238
Joined: 01 Jan 1970, 00:00

Re: Keep the basket between logins

Post by aimeos » 26 Sep 2024, 09:05

That's a question you should ask in a Laravel forum.
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, Image give us a star

Post Reply