CoreShop Multiple Product DataObjects
CoreShop comes with one pre-installed Product Class (CoreShopProduct), which in most cases is enough. In some cases, you might want to use separated classes with different purposes. For example a ProductSet, which consists of multiple Products but also needs to be available for complex price calculations like Price Rules.
First of all, we need to create a new DataObject Class in Pimcore. A basic Purchasable Product only needs to implement \CoreShop\Component\Order\Model\PurchasableInterface
but since we want to allow complex price calculation, we need to implement CoreShop\Component\Core\Model\ProductInterface
.
Note If your Product is very simple and you do not need complex price calculations you then only need to implement
\CoreShop\Component\Order\Model\PurchasableInterface
Easiest way to create the new class is:
- 1: Open Pimcore DataObject Editor
- 2: Add a new Class called ProductSet
-
3: Import CoreShop Default Product Class (
CoreShopProduct.json
) - 4: Adapt to your needs
- 5: Register your ProductSet Class to CoreShop:
<?php
//src/AppBundle/DependencyInjection/Configuration.php
namespace AppBundle\DependencyInjection;
use CoreShop\Bundle\ProductBundle\Pimcore\Repository\ProductRepository;
use CoreShop\Bundle\ResourceBundle\CoreShopResourceBundle;
use CoreShop\Component\Product\Model\ProductInterface;
use CoreShop\Component\Resource\Factory\PimcoreFactory;
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
final class Configuration implements ConfigurationInterface
{
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('app');
$rootNode
->children()
->scalarNode('driver')->defaultValue(CoreShopResourceBundle::DRIVER_DOCTRINE_ORM)->end()
->end()
;
$this->addModelsSection($rootNode);
return $treeBuilder;
}
//Add your configuration here
private function addModelsSection(ArrayNodeDefinition $node)
{
$node
->children()
->arrayNode('pimcore')
->addDefaultsIfNotSet()
->children()
->arrayNode('product_set')
->addDefaultsIfNotSet()
->children()
->variableNode('options')->end()
->scalarNode('path')->defaultValue('products')->end()
->arrayNode('classes')
->addDefaultsIfNotSet()
->children()
->scalarNode('model')->defaultValue('Pimcore\Model\DataObject\ProductSet')->cannotBeEmpty()->end()
->scalarNode('interface')->defaultValue(ProductInterface::class)->cannotBeEmpty()->end()
->scalarNode('factory')->defaultValue(PimcoreFactory::class)->cannotBeEmpty()->end()
->scalarNode('repository')->defaultValue(ProductRepository::class)->cannotBeEmpty()->end()
->scalarNode('install_file')->defaultValue('@CoreShopProductBundle/Resources/install/pimcore/classes/CoreShopProduct.json')->end()
->scalarNode('type')->defaultValue(CoreShopResourceBundle::PIMCORE_MODEL_TYPE_OBJECT)->cannotBeOverwritten(true)->end()
->end()
->end()
->end()
->end()
->end()
->end()
->end()
;
}
}
<?php
//src/AppBundle/DependencyInjection/AppExtension.php
namespace AppBundle\DependencyInjection;
use CoreShop\Bundle\ResourceBundle\DependencyInjection\Extension\AbstractModelExtension;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
class AppExtension extends AbstractModelExtension
{
public function load(array $config, ContainerBuilder $container)
{
$config = $this->processConfiguration($this->getConfiguration([], $container), $config);
$loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
//Register the model to the container
$this->registerPimcoreModels('app', $config['pimcore'], $container);
//Alternative you can do it manually like:
$this->registerPimcoreModels('app', [
'product_set' => [
'path' => '/product-sets',
'classes' => [
'model' => 'Pimcore\Model\DataObject\ProductSet',
'interface' => ProductInterface::class,
'factory' => PimcoreFactory::class,
'type' => CoreShopResourceBundle::PIMCORE_MODEL_TYPE_OBJECT
]
]
], $container);
$loader->load('services.yml');
}
}
- 6: You can now use the new ObjectClass as you wish, CoreShop automatically recognises it as ProductClass and your are allowed to use it in PriceRules.
Note: For the Class to be allowed as href/multihref in Pimcore, you need to adapt following classes as well:
- CoreShopCartItem
- CoreShopOrderItem
- CoreShopQuoteItem
Check for the product field and add your new ProductSet there as allowed references.