Install the Product Labels feature
Edit on GitHubThis document describes how to install the Product Labels feature.
Install feature core
Follow the steps below to install the Alternative Products feature core.
Prerequisites
Install the required features:
NAME | VERSION | INSTALLATION GUIDE |
---|---|---|
Spryker Core | 202404.0 | Install the Spryker Core feature |
Product | 202404.0 | Install the Product feature |
1) Install the required modules
composer require spryker-feature/product-labels:"202404.0" --update-with-dependencies
Make sure the following modules have been installed:
MODULE | EXPECTED DIRECTORY |
---|---|
ProductLabel | vendor/spryker/product-label |
ProductLabelDataImport | vendor/spryker/product-label-data-import |
ProductLabelGui | vendor/spryker/product-label-gui |
ProductLabelSearch | vendor/spryker/product-label-search |
ProductLabelStorage | vendor/spryker/product-label-storage |
2) Set up database schema and transfer objects
- For entity changes to trigger events, adjust the schema definition:
src/Pyz/Zed/ProductLabel/Persistence/Propel/Schema/spy_product_label.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\ProductLabel\Persistence"
package="src.Orm.Zed.ProductLabel.Persistence"
>
<table name="spy_product_label">
<behavior name="event">
<parameter name="spy_product_label_all" column="*"/>
</behavior>
</table>
<table name="spy_product_label_store">
<behavior name="event">
<parameter name="spy_product_label_store_all" column="*"/>
</behavior>
</table>
</database>
src/Pyz/Zed/ProductLabel/Persistence/Propel/Schema/spy_product_label_localized_attributes.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\ProductLabel\Persistence"
package="src.Orm.Zed.ProductLabel.Persistence"
>
<table name="spy_product_label_localized_attributes">
<behavior name="event">
<parameter name="spy_product_label_localized_attributes_all" column="*"/>
</behavior>
</table>
</database>
src/Pyz/Zed/ProductLabel/Persistence/Propel/Schema/spy_product_label_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\ProductLabel\Persistence"
package="src.Orm.Zed.ProductLabel.Persistence"
>
<table name="spy_product_label_product_abstract">
<behavior name="event">
<parameter name="spy_product_label_product_abstract_all" column="*"/>
</behavior>
</table>
</database>
AFFECTED ENTITY | TRIGGERED EVENTS |
---|---|
spy_product_label |
|
spy_product_label_store |
|
spy_product_label_localized_attributes |
|
spy_product_label_product_abstract |
|
- To synchronize the entities without store relations among stores, set up synchronization queue pools:
src/Pyz/Zed/ProductLabelStorage/Persistence/Propel/Schema/spy_product_label_storage.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\ProductLabelStorage\Persistence"
package="src.Orm.Zed.ProductLabelStorage.Persistence">
<table name="spy_product_abstract_label_storage">
<behavior name="synchronization">
<parameter name="queue_pool" value="synchronizationPool"/>
</behavior>
</table>
</database>
- Apply database changes and generate entity and transfer changes:
console propel:install
console transfer:generate
Ensure that the following changes have been applied by checking your database:
DATABASE ENTITY | TYPE | EVENT |
---|---|---|
spy_product_label | table | created |
spy_product_label_store | table | created |
spy_product_label_localized_attributes | table | created |
spy_product_label_product_abstract | table | created |
spy_product_label_dictionary_storage | table | created |
spy_product_abstract_label_storage | table | created |
Ensure that the following changes have been triggered in transfer objects:
TRANSFER | TYPE | EVENT | PATH |
---|---|---|---|
ProductLabel | class | created | src/Generated/Shared/Transfer/ProductLabelTransfer |
ProductLabelCriteria | class | created | src/Generated/Shared/Transfer/ProductLabelCriteriaTransfer |
ProductLabelLocalizedAttributes | class | created | src/Generated/Shared/Transfer/ProductLabelLocalizedAttributesTransfer |
ProductLabelProductAbstract | class | created | src/Generated/Shared/Transfer/ProductLabelProductAbstractTransfer |
ProductLabelProductAbstractRelations | class | created | src/Generated/Shared/Transfer/ProductLabelProductAbstractRelationsTransfer |
ProductLabelResponse | class | created | src/Generated/Shared/Transfer/ProductLabelResponseTransfer |
ProductLabelCollection | class | created | src/Generated/Shared/Transfer/ProductLabelCollectionTransfer |
Pagination | class | created | src/Generated/Shared/Transfer/PaginationTransfer |
StorageProductLabel | class | created | src/Generated/Shared/Transfer/StorageProductLabelTransfer |
Message | class | created | src/Generated/Shared/Transfer/MessageTransfer |
FacetConfig | class | created | src/Generated/Shared/Transfer/FacetConfigTransfer |
StoreRelation | class | created | src/Generated/Shared/Transfer/StoreRelationTransfer |
Store | class | created | src/Generated/Shared/Transfer/StoreTransfer |
ProductLabelAggregateForm | class | created | src/Generated/Shared/Transfer/ProductLabelAggregateFormTransfer |
Money | class | created | src/Generated/Shared/Transfer/MoneyTransfer |
PageMap | class | created | src/Generated/Shared/Transfer/PageMapTransfer |
ProductPageLoad | class | created | src/Generated/Shared/Transfer/ProductPageLoadTransfer |
ProductPageSearch | class | created | src/Generated/Shared/Transfer/ProductPageSearchTransfer |
ProductPayload | class | created | src/Generated/Shared/Transfer/ProductPayloadTransfer |
ProductAbstractLabelStorage | class | created | src/Generated/Shared/Transfer/ProductAbstractLabelStorageTransfer |
ProductLabelDictionaryStorage | class | created | src/Generated/Shared/Transfer/ProductLabelDictionaryStorageTransfer |
ProductLabelDictionaryItem | class | created | src/Generated/Shared/Transfer/ProductLabelDictionaryItemTransfer |
ProductView | class | created | src/Generated/Shared/Transfer/ProductViewTransfer |
SynchronizationData | class | created | src/Generated/Shared/Transfer/SynchronizationDataTransfer |
Locale | class | created | src/Generated/Shared/Transfer/LocaleTransfer |
TabItem | class | created | src/Generated/Shared/Transfer/TabItemTransfer |
TabsView | class | created | src/Generated/Shared/Transfer/TabsViewTransfer |
Filter | class | created | src/Generated/Shared/Transfer/FilterTransfer |
3) Set up behavior
- Set up publishers:
PLUGIN | SPECIFICATION | PREREQUISITES | NAMESPACE |
---|---|---|---|
ProductLabelWritePublisherPlugin | Updates the label data of the product page search when triggered by the provided product label events. | None | Spryker\Zed\ProductLabelSearch\Communication\Plugin\Publisher\ProductLabel |
ProductLabelProductAbstractWritePublisherPlugin | Updates the label data of the product page search when triggered by the provided product label product abstract relation events. | None | Spryker\Zed\ProductLabelSearch\Communication\Plugin\Publisher\ProductLabelProductAbstract |
ProductLabelStoreWritePublisherPlugin | Updates the product abstract data in the search engine when triggered by the provided publish and unpublish events of the product label and product abstract relation. | None | Spryker\Zed\ProductLabelSearch\Communication\Plugin\Publisher\ProductLabelStore |
ProductAbstractLabelWritePublisherPlugin | Updates product abstract data in the storage when triggered by the provided publish and unpublish events of the product label and product abstract relation. | None | Spryker\Zed\ProductLabelStorage\Communication\Plugin\Publisher\ProductAbstractLabel |
ProductLabelDictionaryWritePublisherPlugin | Updates the data of the product label dictionary in the storage when triggered by the provided product label storage events. | None | Spryker\Zed\ProductLabelStorage\Communication\Plugin\Publisher\ProductLabelDictionary |
ProductLabelProductAbstractWritePublisherPlugin | Updates the product abstract data in the storage when triggered by the provided events of product label and product abstract relation. | None | Spryker\Zed\ProductLabelStorage\Communication\Plugin\Publisher\ProductLabelProductAbstract |
ProductLabelDictionaryDeletePublisherPlugin | Removes all the data of the product label dictionary storage when triggered by the provided product label dictionary events. | None | Spryker\Zed\ProductLabelStorage\Communication\Plugin\Publisher\ProductLabelDictionary |
ProductLabelSearchPublisherTriggerPlugin | Allows publishing or re-publishing product label search data manually. | None | Spryker\Zed\ProductLabelSearch\Communication\Plugin\Publisher |
src/Pyz/Zed/Publisher/PublisherDependencyProvider.php
<?php
namespace Pyz\Zed\Publisher;
use Spryker\Zed\ProductLabelSearch\Communication\Plugin\Publisher\ProductLabelSearchPublisherTriggerPlugin
use Spryker\Zed\ProductLabelSearch\Communication\Plugin\Publisher\ProductLabel\ProductLabelWritePublisherPlugin as ProductLabelSearchWritePublisherPlugin;
use Spryker\Zed\ProductLabelSearch\Communication\Plugin\Publisher\ProductLabelProductAbstract\ProductLabelProductAbstractWritePublisherPlugin as ProductLabelProductAbstractSearchWritePublisherPlugin;
use Spryker\Zed\ProductLabelSearch\Communication\Plugin\Publisher\ProductLabelStore\ProductLabelStoreWritePublisherPlugin as ProductLabelStoreSearchWritePublisherPlugin;
use Spryker\Zed\ProductLabelStorage\Communication\Plugin\Publisher\ProductAbstractLabel\ProductAbstractLabelWritePublisherPlugin as ProductAbstractLabelStorageWritePublisherPlugin;
use Spryker\Zed\ProductLabelStorage\Communication\Plugin\Publisher\ProductLabelDictionary\ProductLabelDictionaryDeletePublisherPlugin as ProductLabelDictionaryStorageDeletePublisherPlugin;
use Spryker\Zed\ProductLabelStorage\Communication\Plugin\Publisher\ProductLabelDictionary\ProductLabelDictionaryWritePublisherPlugin as ProductLabelDictionaryStorageWritePublisherPlugin;
use Spryker\Zed\ProductLabelStorage\Communication\Plugin\Publisher\ProductLabelProductAbstract\ProductLabelProductAbstractWritePublisherPlugin as ProductLabelProductAbstractStorageWritePublisherPlugin;
use Spryker\Zed\Publisher\PublisherDependencyProvider as SprykerPublisherDependencyProvider;
class PublisherDependencyProvider extends SprykerPublisherDependencyProvider
{
/**
* @return \Spryker\Zed\PublisherExtension\Dependency\Plugin\PublisherPluginInterface[]
*/
protected function getPublisherPlugins(): array
{
return array_merge(
$this->getProductLabelSearchPlugins(),
$this->getProductLabelStoragePlugins(),
);
}
/**
* @return \Spryker\Zed\PublisherExtension\Dependency\Plugin\PublisherPluginInterface[]
*/
protected function getProductLabelSearchPlugins(): array
{
return [
new ProductLabelSearchWritePublisherPlugin(),
new ProductLabelProductAbstractSearchWritePublisherPlugin(),
new ProductLabelStoreSearchWritePublisherPlugin(),
];
}
/**
* @return \Spryker\Zed\PublisherExtension\Dependency\Plugin\PublisherPluginInterface[]
*/
protected function getProductLabelStoragePlugins(): array
{
return [
new ProductAbstractLabelStorageWritePublisherPlugin(),
new ProductLabelProductAbstractStorageWritePublisherPlugin(),
new ProductLabelDictionaryStorageWritePublisherPlugin(),
new ProductLabelDictionaryStorageDeletePublisherPlugin(),
];
}
/**
* @return array<\Spryker\Zed\PublisherExtension\Dependency\Plugin\PublisherTriggerPluginInterface>
*/
protected function getPublisherTriggerPlugins(): array
{
return [
new ProductLabelSearchPublisherTriggerPlugin(),
];
}
}
Ensure that following is true:
- After creating a product label, you can find the corresponding record in the
spy_product_label_dictionary_storage
table. - After assigning a product label to a product, the corresponding product record contains the assigned label in the
spy_product_abstract_label_storage
table.
- Set up, regenerate, and resync features by setting up the following plugins:
PLUGIN | SPECIFICATION | PREREQUISITES | NAMESPACE |
---|---|---|---|
ProductAbstractLabelPublisherTriggerPlugin | Triggers publish events for the product label data. | None | Spryker\Zed\ProductLabelStorage\Communication\Plugin\Publisher |
ProductLabelDictionaryPublisherTriggerPlugin | Triggers publish events for the product label dictionary data. | None | Spryker\Zed\ProductLabelStorage\Communication\Plugin\Publisher |
ProductAbstractLabelSynchronizationDataRepositoryPlugin | Allows synchronizing the content of the entire spy_product_abstract_label_storage table into the storage. |
None | Spryker\Zed\ProductLabelStorage\Communication\Plugin\Synchronization |
ProductLabelDictionarySynchronizationDataRepositoryPlugin | Allows synchronizing the content of the entire spy_product_label_dictionary_storage table content into the storage. |
None | Spryker\Zed\ProductLabelStorage\Communication\Plugin\Synchronization |
ProductNewLabelUpdaterPlugin | Returns the list of relations of product labels to abstract products to assign or deassign product labels for. The results are used to persist product label relation changes into the database. The plugin is called by the ProductLabelRelationUpdaterConsolecommand. | None | Spryker\Zed\ProductNew\Communication\Plugin |
src/Pyz/Zed/Publisher/PublisherDependencyProvider.php
<?php
namespace Pyz\Zed\Publisher;
use Spryker\Zed\ProductLabelStorage\Communication\Plugin\Publisher\ProductAbstractLabelPublisherTriggerPlugin;
use Spryker\Zed\ProductLabelStorage\Communication\Plugin\Publisher\ProductLabelDictionaryPublisherTriggerPlugin;
use Spryker\Zed\Publisher\PublisherDependencyProvider as SprykerPublisherDependencyProvider;
class PublisherDependencyProvider extends SprykerPublisherDependencyProvider
{
/**
* @return \Spryker\Zed\PublisherExtension\Dependency\Plugin\PublisherTriggerPluginInterface[]
*/
protected function getPublisherTriggerPlugins(): array
{
return [
new ProductAbstractLabelPublisherTriggerPlugin(),
new ProductLabelDictionaryPublisherTriggerPlugin(),
];
}
}
src/Pyz/Zed/ProductLabelStorage/ProductLabelStorageConfig.php
<?php
namespace Pyz\Zed\ProductLabelStorage;
use Spryker\Shared\Publisher\PublisherConfig;
use Pyz\Zed\Synchronization\SynchronizationConfig;
use Spryker\Zed\ProductLabelStorage\ProductLabelStorageConfig as SprykerProductLabelStorageConfig;
class ProductLabelStorageConfig extends SprykerProductLabelStorageConfig
{
/**
* @return string|null
*/
public function getProductAbstractLabelSynchronizationPoolName(): ?string
{
return SynchronizationConfig::DEFAULT_SYNCHRONIZATION_POOL_NAME;
}
/**
* @return string|null
*/
public function getProductLabelDictionarySynchronizationPoolName(): ?string
{
return SynchronizationConfig::DEFAULT_SYNCHRONIZATION_POOL_NAME;
}
/**
* @return string|null
*/
public function getProductAbstractLabelEventQueueName(): ?string
{
return PublisherConfig::PUBLISH_QUEUE;
}
/**
* @return string|null
*/
public function getProductLabelDictionaryEventQueueName(): ?string
{
return PublisherConfig::PUBLISH_QUEUE;
}
}
src/Pyz/Zed/ProductLabelSearch/ProductLabelSearchConfig.php
<?php
namespace Pyz\Zed\ProductLabelSearch;
use Spryker\Shared\Publisher\PublisherConfig;
use Spryker\Zed\ProductLabelSearch\ProductLabelSearchConfig as SprykerProductLabelSearchConfig;
class ProductLabelSearchConfig extends SprykerProductLabelSearchConfig
{
/**
* @return string|null
*/
public function getEventQueueName(): ?string
{
return PublisherConfig::PUBLISH_QUEUE;
}
}
src/Pyz/Zed/Synchronization/SynchronizationDependencyProvider.php
<?php
namespace Pyz\Zed\Synchronization;
use Spryker\Zed\ProductLabelStorage\Communication\Plugin\Synchronization\ProductAbstractLabelSynchronizationDataRepositoryPlugin;
use Spryker\Zed\ProductLabelStorage\Communication\Plugin\Synchronization\ProductLabelDictionarySynchronizationDataRepositoryPlugin;
use Spryker\Zed\Synchronization\SynchronizationDependencyProvider as SprykerSynchronizationDependencyProvider;
class SynchronizationDependencyProvider extends SprykerSynchronizationDependencyProvider
{
/**
* @return \Spryker\Zed\SynchronizationExtension\Dependency\Plugin\SynchronizationDataPluginInterface[]
*/
protected function getSynchronizationDataPlugins(): array
{
return [
new ProductAbstractLabelSynchronizationDataRepositoryPlugin(),
new ProductLabelDictionarySynchronizationDataRepositoryPlugin(),
];
}
}
Ensure that the product label trigger plugin works correctly:
- Fill the
spy_product_label
table with some data. - Run the
console publish:trigger-events -r product_label_dictionary
command. - Ensure that the
spy_product_label_dictionary_storage
table is filled with respective data. - Ensure that the storage entries appear in your system with the
kv:product_label_dictionary:store:locale
mask.
Ensure that the product label synchronization plugin works correctly:
- Fill the
spy_product_label_product_abstract
table with some data. - Run the
console publish:trigger-events -r product_abstract_label
command. - Ensure that the
spy_product_abstract_label_storage
table is filled with respective data. - Ensure that storage entries appear in your system with the
kv:product_abstract_label:id_product_abstract
mask.
src/Pyz/Zed/ProductLabel/ProductLabelDependencyProvider.php
<?php
namespace Pyz\Zed\ProductLabel;
use Spryker\Zed\ProductLabel\ProductLabelDependencyProvider as SprykerProductLabelDependencyProvider;
use Spryker\Zed\ProductNew\Communication\Plugin\ProductNewLabelUpdaterPlugin;
class ProductLabelDependencyProvider extends SprykerProductLabelDependencyProvider
{
/**
* @return \Spryker\Zed\ProductLabel\Dependency\Plugin\ProductLabelRelationUpdaterPluginInterface[]
*/
protected function getProductLabelRelationUpdaterPlugins()
{
return [
new ProductNewLabelUpdaterPlugin(),
];
}
}
Ensure that the product label new works:
- In the Back Office, go to Catalog > Products.
- To create a product, click Create a Product.
- In the NEW FROM and NEW TO fields, enter dates so that the current date is between the entered ones.
- Clisk Save.
- On the Storefront, check that the product is displayed with the new product label.
4) Import data
The following imported entities are used as product labels in Spryker.
- Prepare data according to your requirements using the following demo data:
data/import/product_label.csv
name,is_active,is_dynamic,is_exclusive,front_end_reference,valid_from,valid_to,name.en_US,product_abstract_skus,priority
Label 1,1,0,0,,,,Label 1,"001,002,003",1
Label 2,1,1,0,template,,,Label 2,,2
Label 3,1,1,0,highlight,,,Label 3,,3
NEW,1,1,0,template:tag,,,New,Neu,,2
COLUMN | REQUIRED | DATA TYPE | DATA EXAMPLE | DATA EXPLANATION |
---|---|---|---|---|
name | Yes | string | Label 1 | Unique product label identifier. |
is_active | Yes | integer | 1 | Defines if the product label is available. |
is_dynamic | Yes | integer | 1 | Defines if the product label is dynamic. |
is_exclusive | Yes | integer | 1 | Defines if the product label is exclusive. |
front_end_reference | Yes | string | template:tag | When the label is rendered, this value is used as a part of the CSS selector on the page. |
valid_from | Yes | string | 2020-01-01 | Defines the date on which the product label starts to be displayed. |
valid_to | Yes | string | 2020-02-02 | Defines the date on which the product label stops to be displayed. |
name.en_US | Yes | string | name | Name of the product label for a specific locale. |
product_abstract_skus | Yes | string | “001,002,003” | List of product SKUs to which the product label is added. |
priority | Yes | integer | 3 | Defines the product label position among other product labels on the product details page and the product abstract cart. |
data/import/product_label_store.csv
name,store_name
Label 1,US
Label 1,DE
Label 2,US
Label 3,DE
COLUMN | REQUIRED | DATA TYPE | DATA EXAMPLE | DATA EXPLANATION |
---|---|---|---|---|
name | Yes | string | Label 1 | Unique product label identifier. |
store_name | Yes | string | US | Name of the store to assign the label to. |
- Register the following data import plugins:
PLUGIN | SPECIFICATION | PREREQUISITES | NAMESPACE |
---|---|---|---|
ProductLabelDataImportPlugin | Imports product label data into the database. | None | Spryker\Zed\ProductLabelDataImport\Communication\Plugin |
ProductLabelStoreDataImportPlugin | Imports product label store data into the database. | None | Spryker\Zed\ProductLabelDataImport\Communication\Plugin |
src/Pyz/Zed/DataImport/DataImportDependencyProvider.php
<?php
namespace Pyz\Zed\DataImport;
use Spryker\Zed\ProductLabelDataImport\Communication\Plugin\ProductLabelDataImportPlugin;
use Spryker\Zed\ProductLabelDataImport\Communication\Plugin\ProductLabelStoreDataImportPlugin;
use Spryker\Zed\DataImport\DataImportDependencyProvider as SprykerSynchronizationDependencyProvider;
class DataImportDependencyProvider extends SprykerDataImportDependencyProvider
{
/**
* @return array
*/
protected function getDataImporterPlugins(): array
{
return [
new ProductLabelDataImportPlugin(),
new ProductLabelStoreDataImportPlugin(),
];
}
}
- Import data:
console data:import product-label
console data:import product-label-store
Ensure that the configured data has been added to the spy_product_label
and spy_product_label_store
tables in the database.
Install feature frontend
Follow the steps below to install the feature frontend.
Prerequisites
Install the required features:
NAME | VERSION | INSTALLATION GUIDE |
---|---|---|
Spryker Core | 202404.0 | Install the Spryker Core feature |
Product | 202404.0 | Install the Product feature |
1) Install the required modules
composer require "spryker-feature/product-labels:"202404.0" --update-with-dependencies
Make sure the following modules have been installed:
MODULE | EXPECTED DIRECTORY |
---|---|
ProductLabelWidget | vendor/spryker-shop/product-label-widget |
2) Set up widgets
- Register the following plugins to enable widgets:
PLUGIN | SPECIFICATION | PREREQUISITES | NAMESPACE |
---|---|---|---|
ProductAbstractLabelWidget | Displays the product label assigned to a product. | None | SprykerShop\Yves\ProductLabelWidget\Widget |
src/Pyz/Yves/ShopApplication/ShopApplicationDependencyProvider.php
<?php
namespace Pyz\Yves\ShopApplication;
use SprykerShop\Yves\ProductLabelWidget\ProductAbstractLabelWidget;
use SprykerShop\Yves\ShopApplication\ShopApplicationDependencyProvider as SprykerShopApplicationDependencyProvider;
class ShopApplicationDependencyProvider extends SprykerShopApplicationDependencyProvider
{
/**
* @return string[]
*/
protected function getGlobalWidgets(): array
{
return [
ProductAbstractLabelWidget::class,
];
}
}
Ensure that the following widget has been registered:
MODULE | TEST |
---|---|
ProductLabelWidget | Add the following to a Twig template: {% widget 'ProductAbstractLabelWidget' args [...] only %}{% endwidget %} |
- Enable Javascript and CSS changes:
console frontend:yves:build
Ensure that product labels are displayed on the product details and catalog pages.
Thank you!
For submitting the form