Availability Notification feature integration
Edit on GitHubInstall feature core
Prerequisites
Ensure that the related features are installed:
NAME | VERSION |
---|---|
Mailing and Notifications | 202108.0 |
Inventory Management | 202108.0 |
Product | 202108.0 |
Spryker Core | 202108.0 |
1) Install the required modules using Composer
Install the required modules:
composer require "spryker-feature/availability-notification":"202108.0" --update-with-dependencies
Make sure that the following modules have been installed:
MODULE | EXPECTED DIRECTORY |
---|---|
AvailabilityNotification | vendor/spryker/availability-notification |
2) Set up database schema and transfer objects
Apply database changes, generate entities and transfer changes:
console transfer:generate
console propel:install
console transfer:generate
Make sure that the following changes have been implemented in your database:
DATABASE ENTITY | TYPE | EVENT |
---|---|---|
spy_availability_notification_subscription | table | created |
Make sure that propel entities have been generated successfully by checking their existence. Also, change the generated entity classes to extend from Spryker core classes.
CLASS PATH | EXTENDS |
---|---|
src/Orm/Zed/AvailabilityNotification/Persistence/SpyAvailabilityNotificationSubscription.php | Spryker\Zed\AvailabilityNotification\Persistence\Propel\AbstractSpyAvailabilityNotificationSubscription |
src/Orm/Zed/AvailabilityNotification/Persistence/SpyAvailabilityNotificationSubscriptionQuery.php | Spryker\Zed\AvailabilityNotification\Persistence\Propel\AbstractSpyAvailabilityNotificationSubscriptionQuery |
Make sure that the following changes have been implemented in transfer objects:
TRANSFER | TYPE | EVENT | PATH |
---|---|---|---|
AvailabilityNotificationSubscriptionTransfer | class | created | src/Generated/Shared/Transfer/AvailabilityNotificationSubscriptionTransfer.php |
AvailabilityNotificationSubscriptionResponseTransfer | class | created | src/Generated/Shared/Transfer/AvailabilityNotificationSubscriptionResponseTransfer.php |
AvailabilityNotificationSubscriptionRequestTransfer | class | created | src/Generated/Shared/Transfer/AvailabilityNotificationSubscriptionRequestTransfer.php |
AvailabilityNotificationSubscriptionMailDataTransfer | class | created | src/Generated/Shared/Transfer/AvailabilityNotificationSubscriptionMailDataTransfer.php |
AvailabilityNotificationDataTransfer | class | created | src/Generated/Shared/Transfer/AvailabilityNotificationDataTransfer.php |
CustomerTransfer.availabilityNotificationSubscriptionSkus | column | created | src/Generated/Shared/Transfer/CustomerTransfer.php |
MailTransfer.availabilityNotificationSubscriptionMailData | column | created | src/Generated/Shared/Transfer/MailTransfer.php |
3) Set up behavior
Listening to the availability_notification event
Add the following plugin to your project:
PLUGIN | SPECIFICATION | PREREQUISITES | NAMESPACE |
---|---|---|---|
AvailabilityNotificationSubscriber | This plugin is responsible for listening to and processing product availability changes. | Spryker\Zed\AvailabilityNotification\Business\Subscription |
src/Pyz/Zed/Event/EventDependencyProvider.php
<?php
namespace Pyz\Zed\Event;
use Spryker\Zed\AvailabilityNotification\Communication\Plugin\Event\Subscriber\AvailabilityNotificationSubscriber;
use Spryker\Zed\Event\EventDependencyProvider as SprykerEventDependencyProvider;
class EventDependencyProvider extends SprykerEventDependencyProvider
{
/**
* @return \Spryker\Zed\Event\Dependency\EventSubscriberCollectionInterface
*/
public function getEventSubscriberCollection()
{
$eventSubscriberCollection = parent::getEventSubscriberCollection();
$eventSubscriberCollection->add(new AvailabilityNotificationSubscriber());
return $eventSubscriberCollection;
}
}
To verify that AvailabilityNotificationSubscriber
is working:
- Add a new product and make it unavailable.
- As a customer, subscribe to its availability notifications on Yves.
- Make the product available.
- Check your mailbox for the email about the product’s availability.
Email handling
Add the following plugins to your project:
PLUGIN | SPECIFICATION | PREREQUISITES | NAMESPACE |
---|---|---|---|
AvailabilityNotificationSubscriptionMailTypePlugin | Handles the email sent after subscribing to product availability notification. | Spryker\Zed\AvailabilityNotification\Communication\Plugin\Mail | |
AvailabilityNotificationUnsubscribedMailTypePlugin | Handles the email sent after unsubscribing from product availability notification. | Spryker\Zed\AvailabilityNotification\Communication\Plugin\Mail | |
AvailabilityNotificationMailTypePlugin | Handles the email sent after the product’s availability status change. | None | Spryker\Zed\AvailabilityNotification\Communication\Plugin\Mail |
src/Pyz/Zed/Mail/MailDependencyProvider.php
<?php
namespace Pyz\Zed\Mail;
...
use Spryker\Zed\AvailabilityNotification\Communication\Plugin\Mail\AvailabilityNotificationMailTypePlugin;
use Spryker\Zed\AvailabilityNotification\Communication\Plugin\Mail\AvailabilityNotificationSubscriptionMailTypePlugin;
use Spryker\Zed\AvailabilityNotification\Communication\Plugin\Mail\AvailabilityNotificationUnsubscribedMailTypePlugin;
...
use Spryker\Zed\Kernel\Container;
use Spryker\Zed\Mail\Business\Model\Mail\MailTypeCollectionAddInterface;
...
use Spryker\Zed\Mail\MailDependencyProvider as SprykerMailDependencyProvider;
...
class MailDependencyProvider extends SprykerMailDependencyProvider
{
/**
* @param \Spryker\Zed\Kernel\Container $container
*
* @return \Spryker\Zed\Kernel\Container
*/
public function provideBusinessLayerDependencies(Container $container)
{
$container = parent::provideBusinessLayerDependencies($container);
$container->extend(static::MAIL_TYPE_COLLECTION, function (MailTypeCollectionAddInterface $mailCollection) {
$mailCollection
...
->add(new AvailabilityNotificationUnsubscribedMailTypePlugin())
->add(new AvailabilityNotificationSubscriptionMailTypePlugin())
->add(new AvailabilityNotificationMailTypePlugin())
...
;
return $mailCollection;
});
...
return $container;
}
}
To verify that AvailabilityNotificationSubscriptionMailTypePlugin
, AvailabilityNotificationUnsubscribedMailTypePlugin
and AvailabilityNotificationMailTypePlugin
are working:
- Add a new product.
- On YVES, as a customer, subscribe to its availability notifications.
- Switch the availability status of the product several times.
- Check your mailbox for the emails about the product’s status being switched to available and unavailable.
Customer behavior
Add the following plugins to your project:
PLUGIN | SPECIFICATION | PREREQUISITES | NAMESPACE |
---|---|---|---|
AvailabilityNotificationAnonymizerPlugin | Anonymizes customer data during customer anonymization. | Spryker\Zed\AvailabilityNotification\Communication\Plugin\CustomerAnonymizer | |
AvailabilityNotificationSubscriptionCustomerTransferExpanderPlugin | Expands CustomerTransfer with availability notification subscriptions data. |
Spryker\Zed\AvailabilityNotification\Communication\Plugin\Customer |
src/Pyz/Zed/Customer/CustomerDependencyProvider.php
<?php
namespace Pyz\Zed\Customer;
...
use Spryker\Zed\AvailabilityNotification\Communication\Plugin\Customer\AvailabilityNotificationSubscriptionCustomerTransferExpanderPlugin;
use Spryker\Zed\AvailabilityNotification\Communication\Plugin\CustomerAnonymizer\AvailabilityNotificationAnonymizerPlugin;
...
use Spryker\Zed\Customer\CustomerDependencyProvider as SprykerCustomerDependencyProvider;
...
class CustomerDependencyProvider extends SprykerCustomerDependencyProvider
{
...
/**
* @return \Spryker\Zed\Customer\Dependency\Plugin\CustomerAnonymizerPluginInterface[]
*/
protected function getCustomerAnonymizerPlugins()
{
return [
...
new AvailabilityNotificationAnonymizerPlugin(),
];
}
/**
* @return \Spryker\Zed\Customer\Dependency\Plugin\CustomerTransferExpanderPluginInterface[]
*/
protected function getCustomerTransferExpanderPlugins()
{
return [
...
new AvailabilityNotificationSubscriptionCustomerTransferExpanderPlugin(),
];
}
}
To verify that AvailabilityNotificationAnonymizerPlugin
is working:
- Add a new product.
- On Yves, as a company user, subscribe to its availability notifications.
- Check that the corresponding line is added to the
spy_availability_notification_subscription
table. - Delete this user.
- Check that the line is deleted from the
spy_availability_notification_subscription
table.
To verify that AvailabilityNotificationSubscriptionCustomerTransferExpanderPlugin
is working:
- Add a new product.
- On Yves, as a company user, subscribe to its availability notifications.
- On Yves, go to account overview > Newsletters.
- Check that you are subscribed to the product’s availability notifications.
4) Set up the configuration
You can control whether AvailabilityNotificationFacade::subscribe()
throws an exception \Spryker\Zed\Product\Business\Exception\MissingProductException (if SKU does not exist in the database) or not. You can do it via the AvailabilityNotificationConfig::AVAILABILITY_NOTIFICATION_CHECK_PRODUCT_EXISTS
config setting. If set to false
(by default), then the exception is thrown. If set to true
, then the exception is not thrown, but AvailabilityNotificationFacade::subscribe()
returns the instance of AvailabilityNotificationSubscriptionResponseTransfer::$isSuccess = true
.
src/Pyz/Glue/AvailabilityNotification/AvailabilityNotificationConfig.php
<?php
namespace Pyz\Zed\AvailabilityNotification;
use Spryker\Zed\AvailabilityNotification\AvailabilityNotificationConfig as SprykerAvailabilityNotificationConfig;
class AvailabilityNotificationConfig extends SprykerAvailabilityNotificationConfig
{
protected const AVAILABILITY_NOTIFICATION_CHECK_PRODUCT_EXISTS = true;
}
We recommend setting AVAILABILITY_NOTIFICATION_CHECK_PRODUCT_EXISTS
to true.
Make sure that you are not catching the mentioned above exception somewhere in your Pyz code but use check of $availabilityNotificationSubscriptionResponseTransfer->getIsSuccess()
.
The config setting exists for BC reasons only.
Install feature frontend
Prerequisites
Ensure that the related features are installed:
NAME | VERSION |
---|---|
Mailing & Notifications | 202108.0 |
Inventory Management | 202108.0 |
Product | 202108.0 |
Spryker Core | 202108.0 |
1) Install the required modules using Composer
Install the required modules:
composer require "spryker-feature/availability-notification":"202108.0" --update-with-dependencies
Make sure that the following modules have been installed:
MODULE | EXPECTED DIRECTORY |
---|---|
AvailabilityNotificationPage | vendor/spryker-shop/availability-notification-page |
AvailabilityNotificationPageWidget | vendor/spryker-shop/availability-notification-widget |
2) Add translations
Feature-specific glossary keys:
/data/import/glossary.csv
availability_notification.notify_me,Notify me when back in stock,en_US
availability_notification.notify_me,"Benachrichtigen Sie mich, wenn der Artikel wieder verfügbar ist",de_DE
availability_notification.do_not_notify_me,Do not notify me when back in stock,en_US
availability_notification.do_not_notify_me,"Benachrichtigen Sie mich nicht, wenn der Artikel wieder verfügbar ist",de_DE
availability_notification.subscribed,Successfully subscribed,en_US
availability_notification.subscribed,Erfolgreich abonniert,de_DE
availability_notification.unsubscribed,Successfully unsubscribed,en_US
availability_notification.unsubscribed,Erfolgreich abgemeldet,de_DE
availability_notification.successfully_unsubscribed,"Successfully unsubscribed",en_US
availability_notification.successfully_unsubscribed,"Erfolgreich abbestellt",de_DE
availability_notification.successfully_unsubscribed_text,"You have successfully unsubscribed from being notified when the product is available again",en_US
availability_notification.successfully_unsubscribed_text,"Sie haben erfolgreich eine Benachrichtigung erhalten, wenn das produkt wieder verfügbar ist",de_DE
availability_notification_subscription.mail.subscribed.head,"We just informed our purchase team about your subscription!",en_US
availability_notification_subscription.mail.subscribed.head,"Wir haben unser Einkaufsteam gerade über Ihr Abonnement informiert!",de_DE
availability_notification_subscription.mail.subscribed.body,"You will receive an email when the product will be available again",en_US
availability_notification_subscription.mail.subscribed.body,"Sie erhalten eine E-Mail, sobald das Produkt wieder verfügbar ist",de_DE
availability_notification_subscription.mail.subscribed.subject,"We just informed our purchase team about your subscription!",en_US
availability_notification_subscription.mail.subscribed.subject,"Abonnement für Produktverfügbarkeit",de_DE
availability_notification_subscription.mail.unsubscribed.subject,"You will not be notified when the product %name% will be available again.",en_US
availability_notification_subscription.mail.unsubscribed.subject,"Sie werden nicht benachrichtigt, wenn das Produkt %name% wieder verfügbar ist.",de_DE
availability_notification_subscription.mail.unsubscribed.body,"You will not be notified when the product %name% will be available again.",en_US
availability_notification_subscription.mail.unsubscribed.body,"Sie werden nicht benachrichtigt, wenn das Produkt %name% wieder verfügbar ist.",de_DE
availability_notification_subscription.mail.notification.buy_now,"Buy now",en_US
availability_notification_subscription.mail.notification.buy_now,"Kaufe jetzt",de_DE
availability_notification_subscription.mail.notification.subject,"%name% is available again!",en_US
availability_notification_subscription.mail.notification.subject,"%name% ist wieder verfügbar!",de_DE
availability_notification_subscription.mail.notification.head,"%name% is available again!",en_US
availability_notification_subscription.mail.notification.head,"%name% ist wieder verfügbar",de_DE
availability_notification_subscription.mail.notification.body,"The wait is over, you can not add this product inside your cart.",en_US
availability_notification_subscription.mail.notification.body,"Das Warten hat ein Ende, Sie können dieses Produkt nicht in Ihren Warenkorb legen.",de_DE
availability_notification_subscription.mail.copyright,"<em>Copyright © current year company name, All rights reserved.</em><br><br>",en_US
availability_notification_subscription.mail.copyright,"<em>Copyright © Name des aktuellen Jahres, Alle Rechte vorbehalten.</em><br><br>",de_DE
availability_notification_subscription.mail.unsubscribe,"Want to change how you receive these emails?<br>You can <a target=""_blank"" href=""%link%"" style=""mso-line-height-rule: exactly;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #656565;font-weight: normal;text-decoration: underline;"">unsubscribe from this list</a>.",en_US
availability_notification_subscription.mail.unsubscribe,"Möchten Sie ändern, wie Sie diese E-Mails erhalten?<br>Sie können <a target=""_blank"" href=""%link%"" style=""mso-line-height-rule: exactly;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #656565;font-weight: normal;text-decoration: underline;"">aus dieser Liste austragen</a>.",de_DE
availability_notification.email_address,"Email address",en_US
availability_notification.email_address,"E-Mail-Addresse",de_DE
Import data:
console data:import glossary
Make sure that, in the database, the configured data is added to the spy_glossary
table.
3) Enable controllers
Register the following controller providers in Yves application:
PROVIDER | NAMESPACE | ENABLE CONTROLLER | CONTROLLER SPECIFICATION |
---|---|---|---|
AvailabilityNotificationPageControllerProvider | SprykerShop\Yves\AvailabilityNotificationPage\Plugin\Provider | AvailabilityNotificationPageController | Provides the functionality of subscription removal by subscription key. |
AvailabilityNotificationWidgetControllerProvider | SprykerShop\Yves\AvailabilityNotificationWidget\Plugin\Provider | AvailabilityNotificationSubscriptionController | Provides subscription management functionality for AvailabilityNotificationWidget . |
src/Pyz/Yves/ShopApplication/YvesBootstrap.php
<?php
namespace Pyz\Yves\ShopApplication;
...
use SprykerShop\Yves\AvailabilityNotificationPage\Plugin\Provider\AvailabilityNotificationPageControllerProvider;
use SprykerShop\Yves\AvailabilityNotificationWidget\Plugin\Provider\AvailabilityNotificationWidgetControllerProvider;
...
use SprykerShop\Yves\ShopApplication\YvesBootstrap as SprykerYvesBootstrap;
...
class YvesBootstrap extends SprykerYvesBootstrap
{
...
/**
* @param bool|null $isSsl
*
* @return \SprykerShop\Yves\ShopApplication\Plugin\Provider\AbstractYvesControllerProvider[]
*/
protected function getControllerProviderStack($isSsl)
{
return [
...
new AvailabilityNotificationWidgetControllerProvider($isSsl),
new AvailabilityNotificationPageControllerProvider($isSsl),
...
];
}
}
Make sure that the following URLs are available on Yves:
http://mysprykershop.com/availability-notification/unsubscribe-by-key/{32 characters key}
http://mysprykershop.com/en/availability-notification/unsubscribe-by-key/{32 characters key}
http://mysprykershop.com/de/availability-notification/unsubscribe-by-key/{32 characters key}
If you have any other languages configured, the corresponding links must be available too.
4) Set up widgets
Register the following plugins to enable widgets:
WIDGET | DESCRIPTION | NAMESPACE |
---|---|---|
AvailabilityNotificationSubscriptionWidget | Renders the subscription form on the product details page. | SprykerShop\Yves\AvailabilityNotificationWidget\Widget |
src/Pyz/Yves/ShopApplication/ShopApplicationDependencyProvider.php
<?php
namespace Pyz\Yves\ShopApplication;
use SprykerShop\Yves\AvailabilityNotificationWidget\Widget\AvailabilityNotificationSubscriptionWidget;
use SprykerShop\Yves\ShopApplication\ShopApplicationDependencyProvider as SprykerShopApplicationDependencyProvider;
class ShopApplicationDependencyProvider extends SprykerShopApplicationDependencyProvider
{
/**
* @return string[]
*/
protected function getGlobalWidgets(): array
{
return [
AvailabilityNotificationSubscriptionWidget::class,
];
}
}
Enable Javascript and CSS changes:
console frontend:yves:build
In case you have a custom template, put AvailabilityNotificationSubscriptionWidget
to your src/Pyz/Yves/ProductDetailPage/Theme/default/components/molecules/product-configurator/product-configurator.twig
file:
...
{% set isProductAbstract = data.product.idProductConcrete is empty %}
...
{% if not isAvailable and not isProductAbstract %}
{% widget 'AvailabilityNotificationSubscriptionWidget' args [data.product] only %}{% endwidget %}
{% endif %}
...
Make sure that the availability subscription form is present on the product details page. To do this, find a concrete product that is out of stock and visit its product details page.
Thank you!
For submitting the form