Cart integration

Edit on GitHub
You are browsing a previous version of the document. The latest version is Upcoming release.

This article 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 will provide the ProductImageCartPlugin that you will have to register later in your shop CartDependencyProvider like in a snippet below:

/**
 * @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

Spryker provides the CartVariant module for this purpose. To install the CartVariant module, run:

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;
}