Cart integration

Edit on GitHub

This document describes how to add product variants and product images to an existing cart.

Prerequisites

Before starting make sure you are familiar with the concept of Spryker Super Attributes.

UI Changes

Cart now supports changing the items in the cart by modifying their attributes. If we have a wrong T-Shirt size in the cart we will be able to change it.

Cart now also supports product images out of the box. cart_product_images

If we have products with multiple super attributes we can now, narrowing-down in the cart. product_super_attributes

Installation

Item images in cart

To support images in a cart, install the optional module ProductImageCartConnector by running:

composer require spryker/product-image-cart-connector

This module provides ProductImageCartPlugin that you have to register later in your shop CartDependencyProvider like in the following snippet:

/**
 * @param \Spryker\Zed\Kernel\Container $container
 *
 * @return \Spryker\Zed\Cart\Dependency\ItemExpanderPluginInterface[]
 */
protected function getExpanderPlugins(Container $container)
{
    return [
        // your existing plugins ...
        new ProductImageCartPlugin(),
    ];
}

If your shop uses product bundles, register ExpondBundleItemsWithImagesPlugin in your shop’s CartDependencyProvider as follows:

/**
 * @param \Spryker\Zed\Kernel\Container $container
 *
 * @return \Spryker\Zed\Cart\Dependency\ItemExpanderPluginInterface[]
 */
protected function getExpanderPlugins(Container $container)
{
    return [
	  //your existing plugins
        new ExpandBundleItemsWithImagesPlugin(),
        ];
}
Verification

Make sure the ExpandBundleItemsWithImagesPlugin is registered after the ExpandBundleItemsPlugin plugin.

Cart variants

For this purpose, Spryker provides the CartVariant module.

Install the CartVariant module:

composer require spryker/cart-variant

AttributeMapCollector

To support the mapping between attributes and availability, we need to collect additional data in our attribute map collector. You can do that by adding a single line with SpyProductTableMap::COL_SKU to the getConreteProducts function.

The full function is as follows:

/**
 * @param int $idProductAbstract
 *
 * @return \Orm\Zed\Product\Persistence\SpyProduct[]|\Propel\Runtime\Collection\ObjectCollection
 */
protected function getConcreteProducts($idProductAbstract)
{
    return SpyProductQuery::create()
        ->select([
            SpyProductTableMap::COL_ID_PRODUCT,
            SpyProductTableMap::COL_ATTRIBUTES,
            SpyProductTableMap::COL_SKU,
        ])
        ->withColumn(SpyProductLocalizedAttributesTableMap::COL_ATTRIBUTES, 'localized_attributes')
        ->useSpyProductLocalizedAttributesQuery()
            ->filterByFkLocale($this->locale->getIdLocale())
        ->endUse()
        ->filterByFkProductAbstract($idProductAbstract)
        ->filterByIsActive(true)
        ->find()
        ->toArray(null, false, TableMap::TYPE_CAMELNAME);
}

The filterConcreteProductIds function was changed to the following:

/**
 * @param array $concreteProducts
 *
 * @return array
 */
protected function filterConcreteProductIds(array $concreteProducts)
{
    $concreteProductIds = array_map(function ($product) {
        return $product[SpyProductTableMap::COL_ID_PRODUCT];
    }, $concreteProducts);
    foreach ($concreteProducts as $product) {
        $concreteProductIds[$product[SpyProductTableMap::COL_SKU]] = $product[SpyProductTableMap::COL_ID_PRODUCT];
    }
    asort($concreteProductIds);
    return $concreteProductIds;
}