In today’s digital age, online shopping is becoming increasingly popular, and customers expect easy product comparisons before making a purchase. Building a product comparison tool can significantly enhance the user experience on your Sylius-based website, opening up new possibilities for comparing and selecting products. In this guide, we will outline the steps to create your own product comparer in Sylius.

Step 1: Add and configure attributes for the product

  1. Using the Sylius Admin Panel, add the required attributes for your products in the Attributes tab.

  1. Navigate to the product edit page and locate the ‘Attributes’ tab. Here you can select created attributes and set their values according to a product.

More on Sylius attributes can be found here and here.

I will present two approaches to creating a product comparer. The first one will involve building this functionality from scratch, while in the second approach, we will utilize a popular Wishlist solution to extend and add a comparer.

First approach (from scratch)

Step 1: Create the Comparer Entity

The Comparer entity represents the actual comparison set created by a user. This entity will store information about the comparison, such as the user who created it and the list of products being compared.

Comparer.php

<?php

declare(strict_types=1);

namespace App\Entity;

use Sylius\Component\Resource\Model\ResourceInterface;
use Sylius\Component\Resource\Model\ResourceTrait;
use Sylius\Component\Customer\Model\CustomerInterface;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;

/**
 * @ORM\Entity
 * @ORM\Table(name="app_comparer")
 */
class Comparer implements ResourceInterface
{
    /**
     * @ORM\ManyToOne(targetEntity="Sylius\Component\Customer\Model\CustomerInterface")
     * @ORM\JoinColumn(name="customer_id", referencedColumnName="id", nullable=true)
     */
    protected $customer;

    /**
     * @ORM\OneToMany(targetEntity="ComparerProduct", mappedBy="comparer", cascade={"persist", "remove"})
     */
    protected $comparerProducts;

    public function __construct()
    {
        $this->comparerProducts = new ArrayCollection();
    }
    
    public function getComparerAttributes(string $locale, string $defaultLocale, Collection $products): Collection
    {
        $attributes = new ArrayCollection();
        /** @var ProductInterface $product */
        foreach ($products as $product) {
            foreach ($product->getAttributesByLocale(
                $locale,
                $defaultLocale
            ) as $attribute) {
                if ($attributes->contains($attribute->getName())) {
                    continue;
                }
                
                $attributes->add($attribute->getName());
            }
        }

        return $attributes;
    }

    // ... other getters and setters
}

Step 2: Create the ComparerProduct Entity

The ComparerProduct entity represents a product within a specific comparison set. It will store information about the product, such as its attributes and any additional data needed for comparison.

ComparerProduct.php

<?php

declare(strict_types=1);

namespace App\Entity;

use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Resource\Model\ResourceInterface;
use Sylius\Component\Resource\Model\ResourceTrait;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="app_comparer_product")
 */
class ComparerProduct implements ResourceInterface
{
    /**
     * @ORM\ManyToOne(targetEntity="Comparer", inversedBy="comparerProducts")
     * @ORM\JoinColumn(name="comparer_id", referencedColumnName="id", nullable=false)
     */
    protected $comparer;

    /**
     * @ORM\ManyToOne(targetEntity="Sylius\Component\Core\Model\ProductInterface")
     * @ORM\JoinColumn(name="product_id", referencedColumnName="id", nullable=true)
     */
    protected $product;

// ... getters/setters
}

Step 3: Update the Database Schema

After creating the entities with Doctrine annotations, you need to update your database schema to reflect the changes. Run the following commands:

bin/console doctrine:migrations:diff
bin/console doctrine:migrations:migrate

These commands will generate and execute the necessary database migrations.

Step 4: Code logic for adding products to comparer and displaying results

In this step, we do not present a specific approach because it is an individual matter for each eCommerce system. Adding to the comparer can be implemented on the product listing or each product page. The comparer itself can exist as a separate page or, for example, as a floating widget.

Second approach – extending our Sylius Wishlist Plugin

1. SyliusWishlistPlugin

If you’re using our SyliusWishlistPlugin you can use its classes as a foundation and add the product comparer as an additional feature. For instance, you can introduce a new bulk action to compare selected products.

Sylius - Wishlist
Sylius – Wishlist

2. Get product attributes from the Wishlist entity

 public function getProductsAttributes(string $locale, string $defaultLocale, Collection $products): Collection
  {
      $attributes = new ArrayCollection();

      /** @var ProductInterface $product */
      foreach ($products as $product) {
          foreach ($product->getAttributesByLocale(
              $locale,
              $defaultLocale
          ) as $attribute) {
              if ($attributes->contains($attribute->getName())) {
                  continue;
              }
                
              $attributes->add($attribute->getName());
          }
      }

      return $attributes;
  }

3. Add example logic to display retrieved data

$products = $wishlist->getProductsByIds($productsIds);
$attributes = $wishlist->getProductsAttributes($request->getLocale(), $request->getDefaultLocale(), $products);

return new Response(
    $this->twigEnvironment->render('App/Compare/compare.html.twig', [
        'products' => $products,
        'attributes' => $attributes,
    ])
);

4. Example of product comparison

Sylius/Shopware Plugin Development & Customization

Summary

Building a product comparer in Sylius can greatly enhance the user experience on your eCommerce platform. Whether you opt for the meticulous approach of crafting it from scratch or leverage the SyliusWishlistPlugin for added functionality, the key lies in understanding your specific requirements.