updated some things and made plugin work with snippets and mail-template
//TODO display button on productpage
This commit is contained in:
parent
7510dc362f
commit
b755a8ad82
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "slinicraftet204/notifyifavail",
|
||||
"description": "benachrichtigt Kunden, sobald ein Produkt wieder verfügbar ist",
|
||||
"version": "0.1.41",
|
||||
"version": "0.1.48",
|
||||
"type": "shopware-platform-plugin",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
|
15
plugin.xml
15
plugin.xml
@ -7,19 +7,4 @@
|
||||
<copyright>TTT-Games</copyright>
|
||||
<license>MIT</license>
|
||||
<compatibility minVersion="6.5.0" />
|
||||
|
||||
<administration>
|
||||
<menu>
|
||||
<item>
|
||||
<name>NotifyIfAvail</name>
|
||||
<label>Benachrichtigungs-Einstellungen</label>
|
||||
<parent>sw-settings-index</parent>
|
||||
<position>50</position>
|
||||
<target>sw.mail.template.detail</target>
|
||||
<params>
|
||||
<param name="id">c6d2c6141e9f44c4a3eb110d2c58c823</param>
|
||||
</params>
|
||||
</item>
|
||||
</menu>
|
||||
</administration>
|
||||
</plugin>
|
||||
|
@ -5,18 +5,16 @@ namespace NotifyIfAvail\Controller;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use NotifyIfAvail\Service\NotificationService;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Shopware\Core\Framework\Uuid\Uuid;
|
||||
|
||||
class NotificationController
|
||||
{
|
||||
private NotificationService $notificationService;
|
||||
private LoggerInterface $logger;
|
||||
private Connection $connection;
|
||||
|
||||
public function __construct(NotificationService $notificationService, LoggerInterface $logger)
|
||||
public function __construct(Connection $connection)
|
||||
{
|
||||
$this->notificationService = $notificationService;
|
||||
$this->logger = $logger;
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -31,12 +29,13 @@ class NotificationController
|
||||
return new JsonResponse(['message' => 'Invalid data'], 400);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->notificationService->saveNotification($email, $productId);
|
||||
return new JsonResponse(['message' => 'Successfully subscribed']);
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Fehler beim Speichern der Benachrichtigung: ' . $e->getMessage());
|
||||
return new JsonResponse(['message' => 'An error occurred'], 500);
|
||||
}
|
||||
$this->connection->insert('notifyifavail_plugin_notification', [
|
||||
'id' => Uuid::randomBytes(),
|
||||
'product_id' => Uuid::fromHexToBytes($productId),
|
||||
'email' => $email,
|
||||
'created_at' => (new \DateTime())->format('Y-m-d H:i:s')
|
||||
]);
|
||||
|
||||
return new JsonResponse(['message' => 'Successfully subscribed']);
|
||||
}
|
||||
}
|
||||
|
@ -8,118 +8,13 @@ use Shopware\Core\Framework\Plugin\Context\DeactivateContext;
|
||||
use Shopware\Core\Framework\Plugin\Context\InstallContext;
|
||||
use Shopware\Core\Framework\Plugin\Context\UninstallContext;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Shopware\Core\Content\MailTemplate\Service\MailTemplateService;
|
||||
use Shopware\Core\Framework\Context;
|
||||
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
|
||||
use Shopware\Core\System\Snippet\SnippetService;
|
||||
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
|
||||
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
|
||||
|
||||
class NotifyIfAvail extends Plugin
|
||||
{
|
||||
public function install(InstallContext $context): void
|
||||
{
|
||||
parent::install($context);
|
||||
|
||||
$this->registerMailTemplateType($context->getContext());
|
||||
$this->registerEmailTemplate($context->getContext());
|
||||
$this->registerSnippets($context->getContext());
|
||||
}
|
||||
|
||||
private function registerEmailTemplate(Context $context): void
|
||||
{
|
||||
$mailTemplateRepository = $this->container->get('mail_template.repository');
|
||||
|
||||
$mailTemplateRepository->upsert([
|
||||
[
|
||||
'id' => 'c6d2c6141e9f44c4a3eb110d2c58c823',
|
||||
'mailTemplateTypeId' => '9f5b31d14c9d4b6a8d2e8f01b5b2a3d7', // ID des Mail-Template-Typs
|
||||
'systemDefault' => false,
|
||||
'description' => 'Benachrichtigung, wenn Produkt wieder verfügbar ist',
|
||||
'contentHtml' => file_get_contents(__DIR__ . '/Resources/email-templates/notification_email.html.twig'),
|
||||
'contentPlain' => strip_tags(file_get_contents(__DIR__ . '/Resources/email-templates/notification_email.html.twig')),
|
||||
'subject' => 'Ihr gewünschter Artikel ist wieder verfügbar!'
|
||||
]
|
||||
], $context);
|
||||
}
|
||||
|
||||
|
||||
private function registerMailTemplateType(Context $context): void
|
||||
{
|
||||
$mailTemplateTypeRepository = $this->container->get('mail_template_type.repository');
|
||||
|
||||
$mailTemplateTypeRepository->upsert([
|
||||
[
|
||||
'id' => '9f5b31d14c9d4b6a8d2e8f01b5b2a3d7',
|
||||
'name' => 'Notify If Available Email',
|
||||
'technicalName' => 'notify_if_avail_email',
|
||||
'availableEntities' => ['product' => 'product'],
|
||||
]
|
||||
], $context);
|
||||
}
|
||||
|
||||
|
||||
private function getMailTemplateTypeId(Context $context): ?string
|
||||
{
|
||||
$mailTemplateTypeRepository = $this->container->get('mail_template_type.repository');
|
||||
$criteria = new Criteria();
|
||||
$criteria->addFilter(new EqualsFilter('technicalName', 'notify_if_avail_email'));
|
||||
|
||||
$mailTemplateType = $mailTemplateTypeRepository->search($criteria, $context)->first();
|
||||
|
||||
return $mailTemplateType ? $mailTemplateType->getId() : '9f5b31d14c9d4b6a8d2e8f01b5b2a3d7';
|
||||
}
|
||||
|
||||
|
||||
private function registerSnippets(Context $context): void
|
||||
{
|
||||
$snippetRepository = $this->container->get('snippet.repository');
|
||||
|
||||
$snippetRepository->upsert([
|
||||
[
|
||||
'id' => '1f5b31d14c9d4b6a8d2e8f01b5b2a3d8',
|
||||
'setId' => '0194da4af1f7720a8183c85d4b7fae35', // Standard-Set-ID für Shopware-Snippets
|
||||
'translationKey' => 'NotifyIfAvail.notify_me',
|
||||
'value' => 'Benachrichtigen, wenn verfügbar',
|
||||
'author' => 'NotifyIfAvail Plugin',
|
||||
],
|
||||
[
|
||||
'id' => '2f5b31d14c9d4b6a8d2e8f01b5b2a3d8',
|
||||
'setId' => '0194da4af1f7720a8183c85d4b7fae35',
|
||||
'translationKey' => 'NotifyIfAvail.email_placeholder',
|
||||
'value' => 'Geben Sie Ihre E-Mail-Adresse ein',
|
||||
'author' => 'NotifyIfAvail Plugin',
|
||||
],
|
||||
[
|
||||
'id' => '3f5b31d14c9d4b6a8d2e8f01b5b2a3d8',
|
||||
'setId' => '0194da4af1f7720a8183c85d4b7fae35',
|
||||
'translationKey' => 'NotifyIfAvail.success_message',
|
||||
'value' => 'Sie werden benachrichtigt, sobald der Artikel verfügbar ist.',
|
||||
'author' => 'NotifyIfAvail Plugin',
|
||||
],
|
||||
[
|
||||
'id' => '4f5b31d14c9d4b6a8d2e8f01b5b2a3d8',
|
||||
'setId' => '0194da4af1f7720a8183c85d4c20138e', // Englische ID
|
||||
'translationKey' => 'NotifyIfAvail.notify_me',
|
||||
'value' => 'Notify me when available',
|
||||
'author' => 'NotifyIfAvail Plugin',
|
||||
],
|
||||
[
|
||||
'id' => '5f5b31d14c9d4b6a8d2e8f01b5b2a3d8',
|
||||
'setId' => '0194da4af1f7720a8183c85d4c20138e',
|
||||
'translationKey' => 'NotifyIfAvail.email_placeholder',
|
||||
'value' => 'Enter your email address',
|
||||
'author' => 'NotifyIfAvail Plugin',
|
||||
],
|
||||
[
|
||||
'id' => '6f5b31d14c9d4b6a8d2e8f01b5b2a3d8',
|
||||
'setId' => '0194da4af1f7720a8183c85d4c20138e',
|
||||
'translationKey' => 'NotifyIfAvail.success_message',
|
||||
'value' => 'You will be notified when the item is available.',
|
||||
'author' => 'NotifyIfAvail Plugin',
|
||||
]
|
||||
], $context);
|
||||
$this->createDatabaseTable();
|
||||
}
|
||||
|
||||
public function uninstall(UninstallContext $context): void
|
||||
@ -131,13 +26,17 @@ class NotifyIfAvail extends Plugin
|
||||
parent::uninstall($context);
|
||||
}
|
||||
|
||||
public function activate(ActivateContext $context): void
|
||||
private function createDatabaseTable(): void
|
||||
{
|
||||
parent::activate($context);
|
||||
}
|
||||
|
||||
public function deactivate(DeactivateContext $context): void
|
||||
{
|
||||
parent::deactivate($context);
|
||||
$connection = $this->container->get(Connection::class);
|
||||
$connection->executeStatement("
|
||||
CREATE TABLE IF NOT EXISTS notifyifavail_plugin_notification (
|
||||
id BINARY(16) NOT NULL,
|
||||
product_id BINARY(16) NOT NULL,
|
||||
email VARCHAR(255) NOT NULL,
|
||||
created_at DATETIME(3) NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
");
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1 @@
|
||||
import PluginManager from 'src/plugin-system/plugin.manager';
|
||||
import NotifyMe from './plugin/notify-me.plugin';
|
||||
|
||||
PluginManager.register('NotifyMe', NotifyMe, '[data-notify-me]');
|
||||
import './js/notify-me.js';
|
||||
|
@ -1,35 +0,0 @@
|
||||
import Plugin from 'src/plugin-system/plugin.class';
|
||||
|
||||
export default class NotifyMe extends Plugin {
|
||||
init() {
|
||||
this.notifyButton = this.el;
|
||||
this.notifyForm = this.el.nextElementSibling;
|
||||
this.emailInput = this.notifyForm.querySelector('#notify-me-email');
|
||||
this.submitButton = this.notifyForm.querySelector('#submit-notify');
|
||||
|
||||
this.registerEvents();
|
||||
}
|
||||
|
||||
registerEvents() {
|
||||
this.notifyButton.addEventListener('click', () => this.showForm());
|
||||
this.submitButton.addEventListener('click', () => this.submitForm());
|
||||
}
|
||||
|
||||
showForm() {
|
||||
this.notifyForm.style.display = 'block';
|
||||
}
|
||||
|
||||
submitForm() {
|
||||
const email = this.emailInput.value;
|
||||
const productId = this.notifyButton.dataset.productId;
|
||||
|
||||
fetch('/notification/subscribe', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
body: `email=${encodeURIComponent(email)}&productId=${encodeURIComponent(productId)}`
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => alert(data.message))
|
||||
.catch(error => console.error('Error:', error));
|
||||
}
|
||||
}
|
50
src/Resources/public/js/notify-me.js
Normal file
50
src/Resources/public/js/notify-me.js
Normal file
@ -0,0 +1,50 @@
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
console.log("✅ NotifyMe Script geladen");
|
||||
|
||||
const notifyContainer = document.getElementById('notify-me-container');
|
||||
if (!notifyContainer) {
|
||||
console.error("❌ NotifyMe: Container nicht gefunden!");
|
||||
return;
|
||||
}
|
||||
|
||||
const notifyButton = document.getElementById('notify-me-button');
|
||||
const submitButton = document.getElementById('submit-notify');
|
||||
const emailInput = document.getElementById('notify-me-email');
|
||||
|
||||
if (notifyButton) {
|
||||
notifyButton.addEventListener('click', function () {
|
||||
const email = this.dataset.customerEmail;
|
||||
const productId = this.dataset.productId;
|
||||
sendNotificationRequest(email, productId);
|
||||
});
|
||||
}
|
||||
|
||||
if (submitButton) {
|
||||
submitButton.addEventListener('click', function () {
|
||||
const email = emailInput.value;
|
||||
const productId = this.dataset.productId;
|
||||
|
||||
if (!email) {
|
||||
alert("Bitte geben Sie eine gültige E-Mail-Adresse ein.");
|
||||
return;
|
||||
}
|
||||
|
||||
sendNotificationRequest(email, productId);
|
||||
});
|
||||
}
|
||||
|
||||
function sendNotificationRequest(email, productId) {
|
||||
console.log(`📩 Anfrage für Produkt: ${productId}, Email: ${email}`);
|
||||
|
||||
fetch('/notification/subscribe', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
body: `email=${encodeURIComponent(email)}&productId=${encodeURIComponent(productId)}`
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
alert(data.message);
|
||||
})
|
||||
.catch(error => console.error('❌ Fehler:', error));
|
||||
}
|
||||
});
|
@ -1,16 +0,0 @@
|
||||
{% if product.extensions.notifyIfAvail is defined and product.extensions.notifyIfAvail.enabled %}
|
||||
<div id="notification-container">
|
||||
<button class="btn btn-primary" id="notify-me-button">
|
||||
{{ "NotifyIfAvail.notify_me"|trans }}
|
||||
</button>
|
||||
|
||||
<div id="notify-me-form" style="display: none;">
|
||||
<input type="email" id="notify-me-email" class="form-control"
|
||||
placeholder="{{ 'NotifyIfAvail.email_placeholder'|trans }}" required>
|
||||
<button class="btn btn-success" id="submit-notify">
|
||||
{{ "NotifyIfAvail.notify_me"|trans }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
@ -0,0 +1,32 @@
|
||||
{% block page_product_detail_price %}
|
||||
{{ parent() }}
|
||||
|
||||
<div class="product-detail-price-container">
|
||||
<!-- Standard Preis-Anzeige -->
|
||||
<p class="product-detail-price with-list-price">
|
||||
{{ product.calculatedPrice.unitPrice|currency }}*
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- HIER FÜGE ICH DEN BUTTON DIREKT EIN -->
|
||||
{% if not product.available or product.stock <= 0 %}
|
||||
<div id="notify-me-container" class="product-notify-container mt-3">
|
||||
<h3>{{ "NotifyIfAvail.notify_me"|trans }}</h3>
|
||||
|
||||
{% if app.customer %}
|
||||
<button class="btn btn-primary w-100" id="notify-me-button"
|
||||
data-product-id="{{ product.id }}"
|
||||
data-customer-email="{{ app.customer.email }}">
|
||||
{{ "NotifyIfAvail.notify_me"|trans }}
|
||||
</button>
|
||||
{% else %}
|
||||
<input type="email" id="notify-me-email" class="form-control mb-2"
|
||||
placeholder="{{ 'NotifyIfAvail.email_placeholder'|trans }}" required>
|
||||
<button class="btn btn-primary w-100" id="submit-notify"
|
||||
data-product-id="{{ product.id }}">
|
||||
{{ "NotifyIfAvail.notify_me"|trans }}
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
Loading…
x
Reference in New Issue
Block a user