Skip to main content
Version: 4.0

Create a new Product Type

CoreShop allows you to create a new custom Product Type. The most single interface implementation that can be added to the cart is the CoreShop\Component\Order\Model\PurchasableInterface. You therefore have to at least implement this interface if you want to add a new Product Type and allow it to be added the the cart.

If you need Product Price Rules, Product Specific Price Rules and Quantity Price Rules, you have to go for the CoreShop\Component\Core\Model\ProductInterface. In that case, it is easier to just copy the CoreShopProduct Class Definition and add it as a new Class.

Registering your Product Type

In Order for CoreShop to know that there is a new Purchasable, you have to register your class. The easiest way to do this is, to add this config:

core_shop_resource:
pimcore:
app.my_product:
classes:
model: Pimcore\Model\DataObject\MyProduct
interface: CoreShop\Component\Core\Model\ProductInterface

Or if it's just a Purchasable:

core_shop_resource:
pimcore:
app.my_product:
classes:
model: Pimcore\Model\DataObject\MyProduct
interface: CoreShop\Component\Order\Model\PurchasableInterface

CoreShop will then create separate Services for you, the mains one are the Factory and the Repository (app.repository.my_product, app.factory.my_product). You don't need to use them in your Project, but they are quite important internally for CoreShop.

Price Calculators

Since you added a new Product Class, you also need Price Calculators for it. CoreShop has a few Price Calculators already, but you can add your own.

If you just added a Purchasable, you have to create a new Price Calculator.

To create a new Price Calculator, you need implement the interfaces CoreShop\Component\Order\Calculator\PurchasablePriceCalculatorInterface and CoreShop\Component\Order\Calculator\PurchasableRetailPriceCalculatorInterface.

For how Pricing works in detail, see this: Pricing

<?php

declare(strict_types=1);

namespace App\CoreShop;

use CoreShop\Component\Order\Calculator\PurchasablePriceCalculatorInterface;
use CoreShop\Component\Order\Calculator\PurchasableRetailPriceCalculatorInterface;
use CoreShop\Component\Order\Exception\NoPurchasablePriceFoundException;
use CoreShop\Component\Order\Exception\NoPurchasableRetailPriceFoundException;
use CoreShop\Component\Order\Model\PurchasableInterface;

class MyProductPriceCalculator implements PurchasablePriceCalculatorInterface, PurchasableRetailPriceCalculatorInterface
{
public function getPrice(PurchasableInterface $purchasable, array $context, bool $includingDiscounts = false): int
{
return $this->getRetailPrice($purchasable, $context);
}

public function getRetailPrice(PurchasableInterface $purchasable, array $context): int
{
if (!$purchasable instanceof \Pimcore\Model\DataObject\MyProduct) {
throw new NoPurchasableRetailPriceFoundException(__CLASS__);
}

return 100;
}
}

You then also need to register your new Calculator as a Service:

    App\CoreShop\MyProductPriceCalculator:
tags:
- { name: coreshop.order.purchasable.price_calculator, type: my_product }
- { name: coreshop.order.purchasable.retail_price_calculator, type: my_product }