bumbummen99 / LaravelShoppingcart

A simple shopping cart implementation for Laravel
MIT License
507 stars 235 forks source link

Possibility to extend the CartItem class #124

Open rucky96 opened 3 years ago

rucky96 commented 3 years ago

Hi,

The package seems very powerful to me, congrats.

I understand that you cannot satisfy everyone by adding new functions, each e-shop is different and many require almost unique solutions. I mean, an example is a function to calculate the price of the cart + shipping. Each one needs to do it in a different way. I managed to extend the Cart class to add it but I also have other needs such as doing calculations on each product which are not included in the original package. This requires extending the CartItem class and it is not that simple, at least I have not succeeded (it is also true that I am quite noob). Maybe in the same way one can customize the default calculator?

That is why I think it would be interesting to open the possibility of extending the classes in a simple way, to avoid rewriting the package and adapting it to each e-shop. Actually, in my case it would be necessary to include just two functions, the package is very complete.

johnthart commented 3 years ago

You could add a custom Macro within a service provider, since the Macro trait was added to the Cart class.

This is what I use for example:

        Cart::macro('trackedShipping', function () {
            if ($this->count() >= 3) {
                return true;
            }

            // more code ...

            return false;
        });

Hope this helps

rucky96 commented 3 years ago

Hi @johnthart,

Yes, you are right. But this has the same effect than using an extended class for Cart. What I see complicated is modifying the CartItem class.

johnthart commented 3 years ago

Hi @johnthart,

Yes, you are right. But this has the same effect than using an extended class for Cart. What I see complicated is modifying the CartItem class.

Sorry, you're right. Didn't read far enough.

rucky96 commented 3 years ago

Hi @johnthart ,

No problem. But I think, if possible in a next expansion, it would be fine to change the variable $discount and $taxRate to protected. So we could use functions like total() in an extended Cart class. I would also appreciate if extending the CartItem class were possible.

bumbummen99 commented 3 years ago

Why the close? I think this is a valid issue :) If you can, please reopen so we can keep track of it :+1:

rucky96 commented 3 years ago

OK! @bumbummen99 😊

rucky96 commented 3 years ago

I have successfully extended the Cart class by adding a new service provider and binding the default class to my custom class:

  1. In config/app.php:
//[...]

    'providers' => [
        //[...]

        App\Providers\CartServiceProvider::class,
      ],

//[...]
  1. In app/Providers/CartServiceProvider.php
<?php

namespace App\Providers;

use App\Services\Cart\Cart;
use Gloudemans\Shoppingcart\ShoppingcartServiceProvider;

class CartServiceProvider extends ShoppingcartServiceProvider
{
    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        parent::register();

        $this->app->bind('cart', function($app){
            $session = $app['session'];
            $events = $app['events'];
           return new Cart($session, $events);
        });

    }

    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}
  1. Finally, the file app/Services/Cart/Cart.php:
    
    <?php

namespace App\Services\Cart;

use Gloudemans\Shoppingcart\Cart as DefaultCart;

class Cart extends DefaultCart { // }

rucky96 commented 3 years ago

To extend class CartItem I have repeated the same process but the result has not been satisfactory. I have not gotten Laravel to read the new class

  1. I have added the binding in app/Providers/CartServiceProvider.php
    
    <?php

namespace App\Providers;

use App\Services\Cart\Cart; use App\Services\Cart\CartItem; //<-- I have added this use Gloudemans\Shoppingcart\CartItem as CartItemDefault; //<-- I have added this use Gloudemans\Shoppingcart\ShoppingcartServiceProvider;

class CartServiceProvider extends ShoppingcartServiceProvider { /**


2. The file app/Services/Cart/CartItem.php:

<?php

namespace App\Services\Cart;

use Gloudemans\Shoppingcart\CartItem as DefaultCartItem;

class CartItem extends DefaultCartItem { // }


This is not working for me. Does anyone figure out why?