updated some things and made plugin work with snippets and mail-template

//TODO display button on productpage
This commit is contained in:
Nils 2025-03-06 13:32:24 +01:00
parent 7510dc362f
commit b755a8ad82
Signed by: slinicraftet204
GPG Key ID: 78E12696BAFC2A4B
9 changed files with 109 additions and 198 deletions

View File

@ -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": [

View File

@ -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>

View File

@ -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);
$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']);
} catch (\Exception $e) {
$this->logger->error('Fehler beim Speichern der Benachrichtigung: ' . $e->getMessage());
return new JsonResponse(['message' => 'An error occurred'], 500);
}
}
}

View File

@ -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;
");
}
}

View File

@ -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';

View File

@ -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));
}
}

View 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));
}
});

View File

@ -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 %}

View File

@ -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 %}