Cart

General

General

How can I add a custom code handler?

You can use the addCodeHandler() method to add custom behaviour for specific codes when applied to the cart.

For example you can create a discount code that adds a free sample pack to the cart.

First, define some settings to control this behaviour:

\Aero\Common\Facades\Settings::group('free-sample', function (\Aero\Common\Settings\SettingGroup $group) {
    $group->eloquent('discount', Discount::class);
    $group->eloquent('variant', Variant::class)->searchField('sku', 'sku');
});

Then add a code handler to the cart that consumes these settings:

\Aero\Cart\Cart::addCodeHandler(function (Cart $cart, string $code) {
    $discount = setting('free-sample.discount');

    if (! $discount) {
        return false;
    }

    if ($code !== $discount->code) {
        return false;
    }

    $alreadyApplied = $cart->items()->contains(function (\Aero\Cart\CartItem $item) {
        return $item->meta->get('is_free_sample');
    });

    if ($alreadyApplied) {
        throw new CartModificationException(__('Discount code already applied.'));
    }

    $cartItem = new CartItem(
        setting('free-sample.variant'),
    );

    $cartItem->setName('Free Sample Pack')
        ->setImmutable()
        ->setNotCombinable()
        ->setFree()
        ->setMeta('is_free_sample', true);

    $cart->add($cartItem);

    return true;
});

The aerocargo/automated-add-to-cart module can be used to automatically add items to the cart based on rules.

Cart Items

Cart Items

What is the cart item builder?

The cart item builder is run whenever an item is added to the cart. It builds the item from the request data.

For example, you can add a gift wrap option to an item when the variant has gift wrapping enabled.

First, define a setting on the variant to control whether gift wrapping is available:

\Aero\Catalog\Models\Variant::settings(function (\Aero\Common\Settings\ModelSettingGroup $group) {
    $group->boolean('has_gift_wrap')->default(false);
});

The CartItemBuilder can then use this setting to add the gift wrap option:

\Aero\Store\Pipelines\CartItemBuilder::extend(function (\Aero\Cart\CartItem $item, \Closure $next) {
    if ($item->model->setting('has_gift_wrap')) {
        $item->addOption(
            \Aero\Cart\CartItemOption::create('Gift Wrap')
        );
    }
    
    return $next($item);
});

Parameters

Parameter Type Description
$item \Aero\Cart\CartItem The cart item being built.
$next \Closure The next step in the cart item builder.


Tutorials

Tutorials

How can I add a customer-selected gift wrapping option?

This tutorial will walk you through adding a "Gift wrap" checkbox to the product page, which when selected will add the product to the cart with the additional £1 charge associated with it being gift wrapped.

First, define some settings to control the behaviour of gift wrapping:

\Aero\Common\Facades\Settings::group('gift-wrap', function (\Aero\Common\Settings\SettingGroup $group) {
    $group->float('price')->default(100)->map(function ($value) {
        return new \Aero\Cart\CartPrice(request()->store()->currency, $value ?? 0);
    });
});
\Aero\Catalog\Models\Variant::settings(function (\Aero\Common\Settings\ModelSettingGroup $group) {
    $group->boolean('has_gift_wrap')->default(false);
});

Now, add a macro for has_gift_wrap so that we can cast it to js, so that it will be available in Vue:

\Aero\Catalog\Models\Variant::macro('getHasGiftWrapAttribute', function () {
    return $this->setting('has_gift_wrap');
});

Aero\Catalog\Models\Variant::addCastToJs('has_gift_wrap');

We can now display a checkbox on the product.twig page when a variant supports it:

<div v-if="variant && variant.has_gift_wrap">
    <input type="checkbox" id="gift-wrap">
    <label for="gift-wrap">Gift Wrap? ({{ setting('gift-wrap.price') }})</label>
</div>

And then we listen to an item being added to the cart and set the has_gift_wrap bool from this checkbox:

{% js %}
    <script>
        window.AeroEvents.on('product.add-to-cart', (data) => {
            const el = document.getElementById('gift-wrap');

            data.has_gift_wrap = el?.checked ?? false;

            return data;
        });
    </script>
{% endjs %}

Finally, we extend the cart item builder to add the gift wrap option when selected:

\Aero\Store\Pipelines\CartItemBuilder::extend(function (\Aero\Cart\CartItem $item, \Closure $next) {
    $hasGiftWrap = $item->model->setting('has_gift_wrap') && request()->get('has_gift_wrap');

    if ($hasGiftWrap) {
        $price = setting('gift-wrap.price');

        $option = \Aero\Cart\CartItemOption::create('Gift Wrap');

        $option->setPriceInc($price->inc()->value);

        $item->addOption($option)->setNotCombinable();
    }

    return $next($item);
});

Checkout the aerocargo/product-options module, for an easier way to do things like this.