Marketplace Product feature integration
Edit on GitHubThis document describes how to integrate the Marketplace Product feature into a Spryker project.
Install feature core
Follow the steps below to install the Marketplace Product feature core.
Prerequisites
To start feature integration, integrate the required features:
NAME | VERSION | INTEGRATION GUIDE |
---|---|---|
Spryker Core | 202108.0 | Spryker Core feature integration |
Marketplace Merchant | 202108.0 | Marketplace Merchant feature integration |
Product | 202108.0 | Product feature integration |
1) Install the required modules using Composer
Install the required modules:
composer require spryker-feature/marketplace-product:"202108.0" --update-with-dependencies
Make sure that the following modules have been installed:
MODULE | EXPECTED DIRECTORY |
---|---|
MerchantProduct | vendor/spryker/merchant-product |
MerchantProductDataImport | vendor/spryker/merchant-product-data-import |
MerchantProductGui | vendor/spryker/merchant-product-gui |
MerchantProductSearch | vendor/spryker/merchant-product-search |
MerchantProductStorage | vendor/spryker/merchant-product-storage |
MerchantProductWidget | vendor/spryker-shop/merchant-product-widget |
2) Set up the database schema and transfer objects
Adjust the schema definition so that entity changes will trigger the events:
src/Pyz/Zed/MerchantProduct/Persistence/Propel/Schema/spy_merchant_product_abstract.schema.xml
<?xml version="1.0"?>
<database xmlns="spryker:schema-01"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
name="zed"
xsi:schemaLocation="spryker:schema-01 https://static.spryker.com/schema-01.xsd"
namespace="Orm\Zed\MerchantProduct\Persistence"
package="src.Orm.Zed.MerchantProduct.Persistence">
<table name="spy_merchant_product_abstract" phpName="SpyMerchantProductAbstract">
<behavior name="event">
<parameter name="spy_merchant_product_abstract_all" column="*"/>
</behavior>
</table>
</database>
Apply database changes and generate entity and transfer changes:
console transfer:generate
console propel:install
console transfer:generate
Verify that the following changes have been applied by checking your database:
DATABASE ENTITY | TYPE | EVENT |
---|---|---|
spy_merchant_product_abstract | table | created |
Generate transfer changes:
console transfer:generate
Make sure that the following changes have been applied in transfer objects:
TRANSFER | TYPE | EVENT | PATH |
---|---|---|---|
MerchantProductCriteria | class | Created | src/Generated/Shared/Transfer/MerchantProductCriteriaTransfer |
MerchantProduct | class | Created | src/Generated/Shared/Transfer/MerchantProductTransfer |
MerchantProductCollection | class | Created | src/Generated/Shared/Transfer/MerchantProductCollectionTransfer |
ProductAbstractMerchant | class | Created | src/Generated/Shared/Transfer/ProductAbstractMerchantTransfer |
MerchantSearchCollection | class | Created | src/Generated/Shared/Transfer/MerchantSearchCollectionTransfer |
MerchantProductStorage | class | Created | src/Generated/Shared/Transfer/MerchantProductStorageTransfer |
ProductAbstract.idMerchant | property | Created | src/Generated/Shared/Transfer/ProductAbstractTransfer |
MerchantProductView | class | Created | src/Generated/Shared/Transfer/MerchantProductViewTransfer |
3) Add translations
Generate new translation cache for Zed:
console translator:generate-cache
4) Configure export to Redis and Elasticsearch
Install the following plugins:
PLUGIN | DESCRIPTION | PREREQUISITES | NAMESPACE |
---|---|---|---|
Merchant\MerchantProductSearchWritePublisherPlugin | Publishes the product by merchant ids to ES. | Spryker\Zed\MerchantProductSearch\Communication\Plugin\Publisher | |
MerchantProduct\MerchantProductSearchWritePublisherPlugin | Publishes the product by merchant product abstract ids to ES. | Spryker\Zed\MerchantProductSearch\Communication\Plugin\Publisher | |
MerchantUpdatePublisherPlugin | Publishes the product by merchant ids to Redis. | Spryker\Zed\MerchantProductStorage\Communication\Plugin\Publisher\Merchant | |
MerchantProductWritePublisherPlugin | Publishes the product by merchant product abstract ids to Redis. | Spryker\Zed\MerchantProductStorage\Communication\Plugin\Publisher\MerchantProduct |
src/Pyz/Zed/Publisher/PublisherDependencyProvider.php
<?php
namespace Pyz\Zed\Publisher;
use Spryker\Zed\MerchantProductSearch\Communication\Plugin\Publisher\Merchant\MerchantProductSearchWritePublisherPlugin as MerchantMerchantProductSearchWritePublisherPlugin;
use Spryker\Zed\MerchantProductSearch\Communication\Plugin\Publisher\MerchantProduct\MerchantProductSearchWritePublisherPlugin;
use Spryker\Zed\MerchantProductStorage\Communication\Plugin\Publisher\Merchant\MerchantUpdatePublisherPlugin;
use Spryker\Zed\MerchantProductStorage\Communication\Plugin\Publisher\MerchantProduct\MerchantProductWritePublisherPlugin;
use Spryker\Zed\Publisher\PublisherDependencyProvider as SprykerPublisherDependencyProvider;
class PublisherDependencyProvider extends SprykerPublisherDependencyProvider
{
/**
* @return array
*/
protected function getPublisherPlugins(): array
{
return [
new MerchantProductWritePublisherPlugin(),
new MerchantUpdatePublisherPlugin(),
new MerchantMerchantProductSearchWritePublisherPlugin(),
new MerchantProductSearchWritePublisherPlugin(),
];
}
}
Make sure that the merchant product data appears in the search engine and in the storage.
5) Set up behavior
Enable the following behaviors by registering the plugins:
PLUGIN | DESCRIPTION | PREREQUISITES | NAMESPACE |
---|---|---|---|
MerchantProductProductAbstractViewActionViewDataExpanderPlugin | Expands view data for abstract product with merchant data. | Spryker\Zed\MerchantProductGui\Communication\Plugin\ProductManagement | |
MerchantProductProductAbstractListActionViewDataExpanderPlugin | Expands product list data for abstract product data for merchant filter. | Spryker\Zed\MerchantProductGui\Communication\Plugin\ProductManagement | |
MerchantProductProductTableQueryCriteriaExpanderPlugin | Expands QueryCriteriaTransfer with QueryJoinTransfer for filtering by idMerchant. | Spryker\Zed\MerchantProductGui\Communication\Plugin\ProductManagement | |
MerchantProductAbstractMapExpanderPlugin | Adds merchant names to product abstract search data. | Spryker\Zed\MerchantProductSearch\Communication\Plugin\ProductPageSearch | |
MerchantProductPageDataExpanderPlugin | Expands the provided ProductAbstractPageSearch transfer object’s data by merchant names. | Spryker\Zed\MerchantProductSearch\Communication\Plugin\ProductPageSearch | |
MerchantProductPageDataLoaderPlugin | Expands ProductPageLoadTransfer object with merchant data. | Spryker\Zed\MerchantProductSearch\Communication\Plugin\ProductPageSearch | |
MerchantProductAbstractStorageExpanderPlugin | Expands product abstract storage data with merchant references. | Spryker\Zed\MerchantProductStorage\Communication\Plugin\ProductStorage | |
MerchantProductProductAbstractPostCreatePlugin | Creates a new merchant product abstract entity if ProductAbstractTransfer.idMerchant is set. |
None | Spryker\Zed\MerchantProduct\Communication\Plugin\Product |
src/Pyz/Zed/Product/ProductDependencyProvider.php
<?php
namespace Pyz\Zed\Product;
use Spryker\Zed\MerchantProduct\Communication\Plugin\Product\MerchantProductProductAbstractPostCreatePlugin;
class ProductDependencyProvider extends SprykerProductDependencyProvider
{
/**
* @return array<\Spryker\Zed\ProductExtension\Dependency\Plugin\ProductAbstractPostCreatePluginInterface>
*/
protected function getProductAbstractPostCreatePlugins(): array
{
return [
new MerchantProductProductAbstractPostCreatePlugin(),
];
}
}
Make sure that you can create a new product in the Merchant Portal and observe it after creation in the product data table.
src/Pyz/Zed/ProductManagement/ProductManagementDependencyProvider.php
<?php
namespace Pyz\Zed\ProductManagement;
use Spryker\Zed\MerchantGui\Communication\Plugin\ProductManagement\MerchantProductAbstractListActionViewDataExpanderPlugin;
use Spryker\Zed\MerchantProductGui\Communication\Plugin\ProductManagement\MerchantProductProductAbstractViewActionViewDataExpanderPlugin;
use Spryker\Zed\MerchantProductGui\Communication\Plugin\ProductManagement\MerchantProductProductTableQueryCriteriaExpanderPlugin;
class ProductManagementDependencyProvider extends SprykerProductManagementDependencyProvider
{
/**
* @return array<\Spryker\Zed\ProductManagementExtension\Dependency\Plugin\ProductAbstractViewActionViewDataExpanderPluginInterface>
*/
protected function getProductAbstractViewActionViewDataExpanderPlugins(): array
{
return [
new MerchantProductProductAbstractViewActionViewDataExpanderPlugin(),
];
}
/**
* @return array<\Spryker\Zed\ProductManagementExtension\Dependency\Plugin\ProductTableQueryCriteriaExpanderPluginInterface>
*/
protected function getProductTableQueryCriteriaExpanderPluginInterfaces(): array
{
return [
new MerchantProductProductTableQueryCriteriaExpanderPlugin(),
];
}
/**
* @return array<\Spryker\Zed\ProductManagementExtension\Dependency\Plugin\ProductAbstractListActionViewDataExpanderPluginInterface>
*/
protected function getProductAbstractListActionViewDataExpanderPlugins(): array
{
return [
new MerchantProductAbstractListActionViewDataExpanderPlugin(),
];
}
}
Make sure that you can filter products by merchant in http://zed.de.demo-spryker.com/product-management
.
Make sure that you can see the merchant name in http://zed.de.demo-spryker.com/product-management/view?id-product-abstract={id-product-abstract}}
. (Applicable only for products that are assigned to some merchant. See import step.)
src/Pyz/Zed/ProductPageSearch/ProductPageSearchDependencyProvider.php
<?php
namespace Pyz\Zed\ProductPageSearch;
use Spryker\Shared\MerchantProductSearch\MerchantProductSearchConfig;
use Spryker\Zed\MerchantProductSearch\Communication\Plugin\ProductPageSearch\MerchantProductAbstractMapExpanderPlugin;
use Spryker\Zed\MerchantProductSearch\Communication\Plugin\ProductPageSearch\MerchantProductPageDataExpanderPlugin as MerchantMerchantProductPageDataExpanderPlugin;
use Spryker\Zed\MerchantProductSearch\Communication\Plugin\ProductPageSearch\MerchantProductPageDataLoaderPlugin as MerchantMerchantProductPageDataLoaderPlugin;
use Spryker\Zed\ProductPageSearch\ProductPageSearchDependencyProvider as SprykerProductPageSearchDependencyProvider;
class ProductPageSearchDependencyProvider extends SprykerProductPageSearchDependencyProvider
{
/**
* @return array<\Spryker\Zed\ProductPageSearch\Dependency\Plugin\ProductPageDataExpanderInterface>
*/
protected function getDataExpanderPlugins()
{
$dataExpanderPlugins = [];
$dataExpanderPlugins[MerchantProductSearchConfig::PLUGIN_MERCHANT_PRODUCT_DATA] = new MerchantMerchantProductPageDataExpanderPlugin();
return $dataExpanderPlugins;
}
/**
* @return array<\Spryker\Zed\ProductPageSearchExtension\Dependency\Plugin\ProductAbstractMapExpanderPluginInterface>
*/
protected function getProductAbstractMapExpanderPlugins(): array
{
return [
new MerchantProductAbstractMapExpanderPlugin(),
];
}
/**
* @return array<\Spryker\Zed\ProductPageSearchExtension\Dependency\Plugin\ProductPageDataLoaderPluginInterface>
*/
protected function getDataLoaderPlugins()
{
return [
new MerchantMerchantProductPageDataLoaderPlugin(),
];
}
}
Make sure the de_page
Elasticsearch index for any product that belongs (see spy_merchant_product_abstract
) to active and approved merchant, contains merchant names. (indexes can be accessed by any Elasticsearch client, for example, Kibana. For Docker configuration details, see Configuring services.
src/Pyz/Zed/ProductStorage/ProductStorageDependencyProvider.php
<?php
namespace Pyz\Zed\ProductStorage;
use Spryker\Zed\MerchantProductStorage\Communication\Plugin\ProductStorage\MerchantProductAbstractStorageExpanderPlugin;
use Spryker\Zed\ProductStorage\ProductStorageDependencyProvider as SprykerProductStorageDependencyProvider;
class ProductStorageDependencyProvider extends SprykerProductStorageDependencyProvider
{
/**
* @return array<\Spryker\Zed\ProductStorageExtension\Dependency\Plugin\ProductAbstractStorageExpanderPluginInterface>
*/
protected function getProductAbstractStorageExpanderPlugins(): array
{
return [
new MerchantProductAbstractStorageExpanderPlugin(),
];
}
}
Make sure that data contains merchant_references
for marketplace products in the spy_product_abstract_storage
.
6) Import merchant product data
Prepare your data according to your requirements using the demo data:
data/import/common/common/marketplace/merchant_product.csv
sku,merchant_reference,is_shared
001,MER000001,1
002,MER000001,1
003,MER000001,1
004,MER000001,1
005,MER000001,1
006,MER000001,1
007,MER000001,1
008,MER000001,1
009,MER000001,1
010,MER000001,1
011,MER000001,1
012,MER000001,1
013,MER000001,1
014,MER000001,1
015,MER000001,1
016,MER000001,1
017,MER000001,1
018,MER000001,1
019,MER000001,1
020,MER000001,1
021,MER000001,1
022,MER000001,1
023,MER000001,1
024,MER000001,1
025,MER000001,1
026,MER000001,1
027,MER000001,1
028,MER000001,1
029,MER000001,1
030,MER000001,1
031,MER000001,1
032,MER000001,1
033,MER000001,1
034,MER000001,1
035,MER000001,1
036,MER000001,1
037,MER000001,1
038,MER000001,1
039,MER000001,1
040,MER000001,1
041,MER000001,1
042,MER000001,1
043,MER000001,1
044,MER000001,1
045,MER000001,1
046,MER000001,1
047,MER000001,1
048,MER000001,1
049,MER000001,1
050,MER000001,1
051,MER000001,1
052,MER000001,1
053,MER000001,1
054,MER000001,1
055,MER000001,1
056,MER000001,1
057,MER000001,1
058,MER000001,1
059,MER000001,1
060,MER000001,1
061,MER000001,1
062,MER000001,1
063,MER000001,1
064,MER000001,1
065,MER000001,1
066,MER000001,1
067,MER000001,1
068,MER000001,1
069,MER000001,1
070,MER000001,1
071,MER000001,1
072,MER000001,1
074,MER000001,1
075,MER000001,1
076,MER000001,1
077,MER000001,1
078,MER000001,1
079,MER000001,1
080,MER000001,1
081,MER000001,1
082,MER000001,1
083,MER000001,1
084,MER000001,1
085,MER000001,1
086,MER000001,1
087,MER000001,1
088,MER000001,1
089,MER000001,1
090,MER000001,1
091,MER000001,1
092,MER000001,1
093,MER000001,1
094,MER000001,1
095,MER000001,1
096,MER000001,1
097,MER000001,1
098,MER000001,1
099,MER000001,1
100,MER000001,1
101,MER000001,1
102,MER000001,1
103,MER000001,1
104,MER000001,1
105,MER000001,1
106,MER000001,1
107,MER000001,1
108,MER000001,1
109,MER000001,1
110,MER000001,1
111,MER000001,1
184,MER000002,1
185,MER000002,1
186,MER000002,1
187,MER000002,1
188,MER000002,1
189,MER000002,1
190,MER000002,1
191,MER000002,1
192,MER000002,1
193,MER000002,1
194,MER000002,1
195,MER000002,1
196,MER000002,1
197,MER000002,1
198,MER000002,1
199,MER000002,1
200,MER000002,1
201,MER000002,1
202,MER000002,1
203,MER000002,1
204,MER000002,1
205,MER000002,1
206,MER000002,1
207,MER000002,1
208,MER000002,1
209,MER000002,1
COLUMN | REQUIRED | DATA TYPE | DATA EXAMPLE | DATA EXPLANATION |
---|---|---|---|---|
sku | ✓ | string | 091 | Product identifier. |
merchant_reference | ✓ | string | roan-gmbh-und-co-k-g | Merchant identifier. |
is_shared | ✓ | string | 1 | Defines if other merchant can create product offers for this merchant product. |
Register the following plugins to enable data import:
PLUGIN | SPECIFICATION | PREREQUISITES | NAMESPACE |
---|---|---|---|
MerchantProductDataImportPlugin | Imports merchant product data into the database. | Spryker\Zed\MerchantProductDataImport\Communication\Plugin |
src/Pyz/Zed/DataImport/DataImportDependencyProvider.php
<?php
namespace Pyz\Zed\DataImport;
use Spryker\Zed\DataImport\DataImportDependencyProvider as SprykerDataImportDependencyProvider;
use Spryker\Zed\MerchantProductDataImport\Communication\Plugin\MerchantProductDataImportPlugin;
class DataImportDependencyProvider extends SprykerDataImportDependencyProvider
{
protected function getDataImporterPlugins(): array
{
return [
new MerchantProductDataImportPlugin(),
];
}
}
data/import/local/full_EU.yml
version: 0
actions:
- data_entity: merchant-product
source: data/import/common/common/marketplace/merchant_product.csv
data/import/local/full_US.yml
version: 0
actions:
- data_entity: merchant-product
source: data/import/common/common/marketplace/merchant_product.csv
Import data:
console data:import merchant-product
Make sure that the imported data is added to the spy_merchant_product
table.
Install feature frontend
Follow the steps below to install the Marketplace Product feature frontend.
1) Set up widgets
Register the following plugins to enable widgets:
PLUGIN | DESCRIPTION | Prerequisites | NAMESPACE |
---|---|---|---|
MerchantProductWidget | Displays alternative product. | SprykerShop\Yves\MerchantProductWidget\Widget |
<?php
namespace Pyz\Yves\ShopApplication;
use SprykerShop\Yves\MerchantProductWidget\Widget\MerchantProductWidget;
use SprykerShop\Yves\MerchantProductWidget\Widget\ProductSoldByMerchantWidget;
use SprykerShop\Yves\ShopApplication\ShopApplicationDependencyProvider as SprykerShopApplicationDependencyProvider;
class ShopApplicationDependencyProvider extends SprykerShopApplicationDependencyProvider
{
/**
* @return array<string>
*/
protected function getGlobalWidgets(): array
{
return [
MerchantProductWidget::class,
ProductSoldByMerchantWidget::class,
];
}
}
Enable Javascript and CSS changes:
console frontend:yves:build
Make sure that for the marketplace products you can see the merchant name on the product details page.
Make sure that when you add merchant product to cart, on a cart page is has the Sold By widget displayed.
2) Add Yves translations
Append glossary according to your configuration:
data/import/common/common/glossary.csv
merchant_product.message.invalid,Product "%sku%" with Merchant "%merchant_reference%" not found.,en_US
merchant_product.message.invalid,Der Produkt "%sku%" mit dem Händler "%merchant_reference%" ist nicht gefunden.,de_DE
merchant_product.sold_by,Sold by,en_US
merchant_product.sold_by,Verkauft durch,de_DE
product.filter.merchant_name,Merchant,en_US
product.filter.merchant_name,Händler,de_DE
Import data:
console data:import glossary
Make sure that the configured data is added to the spy_glossary_key
and spy_glossary_translation
tables in the database.
3) Set up behavior
Enable the following behaviors by registering the plugins:
PLUGIN | DESCRIPTION | PREREQUISITES | NAMESPACE |
---|---|---|---|
MerchantProductMerchantNameSearchConfigExpanderPlugin | Expands facet configuration with merchant name filter. | Spryker\Client\MerchantProductSearch\Plugin\Search | |
ProductViewMerchantProductExpanderPlugin | Expands ProductView transfer object with merchant reference. | Spryker\Client\MerchantProductStorage\Plugin\ProductStorage |
src/Pyz/Client/Search/SearchDependencyProvider.php
<?php
namespace Pyz\Client\Search;
use Spryker\Client\Kernel\Container;
use Spryker\Client\MerchantProductSearch\Plugin\Search\MerchantProductMerchantNameSearchConfigExpanderPlugin;
use Spryker\Client\Search\SearchDependencyProvider as SprykerSearchDependencyProvider;
class SearchDependencyProvider extends SprykerSearchDependencyProvider
{
/**
* @param \Spryker\Client\Kernel\Container $container
*
* @return array<\Spryker\Client\SearchExtension\Dependency\Plugin\SearchConfigExpanderPluginInterface>
*/
protected function createSearchConfigExpanderPlugins(Container $container): array
{
$searchConfigExpanderPlugins = parent::createSearchConfigExpanderPlugins($container);
$searchConfigExpanderPlugins[] = new MerchantProductMerchantNameSearchConfigExpanderPlugin();
return $searchConfigExpanderPlugins;
}
}
src/Pyz/Client/SearchElasticsearch/SearchElasticsearchDependencyProvider.php
<?php
namespace Pyz\Client\SearchElasticsearch;
use Spryker\Client\Kernel\Container;
use Spryker\Client\MerchantProductSearch\Plugin\Search\MerchantProductMerchantNameSearchConfigExpanderPlugin;
use Spryker\Client\SearchElasticsearch\SearchElasticsearchDependencyProvider as SprykerSearchElasticsearchDependencyProvider;
class SearchElasticsearchDependencyProvider extends SprykerSearchElasticsearchDependencyProvider
{
/**
* @param \Spryker\Client\Kernel\Container $container
*
* @return array<\Spryker\Client\SearchExtension\Dependency\Plugin\SearchConfigExpanderPluginInterface>
*/
protected function getSearchConfigExpanderPlugins(Container $container): array
{
return [
new MerchantProductMerchantNameSearchConfigExpanderPlugin(),
];
}
}
Make sure that when you enter the merchant name in the search field, the return list contains marketplace products.
src/Pyz/Client/ProductStorage/ProductStorageDependencyProvider.php
<?php
namespace Pyz\Client\ProductStorage;
use Spryker\Client\MerchantProductStorage\Plugin\ProductStorage\ProductViewMerchantProductExpanderPlugin;
use Spryker\Client\ProductStorage\ProductStorageDependencyProvider as SprykerProductStorageDependencyProvider;
class ProductStorageDependencyProvider extends SprykerProductStorageDependencyProvider
{
/**
* @return array<\Spryker\Client\ProductStorage\Dependency\Plugin\ProductViewExpanderPluginInterface>
*/
protected function getProductViewExpanderPlugins()
{
return [
new ProductViewMerchantProductExpanderPlugin(),
];
}
}
Make sure that the merchant product is selected on the product details page by default.
Related features
FEATURE | REQUIRED FOR THE CURRENT FEATURE | INTEGRATION GUIDE |
---|---|---|
Marketplace Product API | Glue API: Marketplace Product feature integration | |
Marketplace Product + Marketplace Product Offer | Marketplace Product + Marketplace Product Offer feature integration | |
Marketplace Product + Inventory Management | Marketplace Product + Inventory Management feature integration | |
Marketplace Product + Cart | Marketplace Product + Cart feature integration |
Thank you!
For submitting the form