Cart integration

Edit on GitHub

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{height=”” width=””}

If we have products with multiple super attributes we can now, narrowing-down in the cart. product_super_attributes{height=”” width=””}

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