522 lines
18 KiB
PHP
522 lines
18 KiB
PHP
<?php
|
|
/**
|
|
* Copyright seit 2024 Webshop System
|
|
*
|
|
* Admin-Newsletter-Controller für das Webshop-System
|
|
*
|
|
* @author Webshop System
|
|
* @license GPL v3
|
|
*/
|
|
|
|
namespace App\Admin\Controllers;
|
|
|
|
use Doctrine\DBAL\DriverManager;
|
|
use Doctrine\DBAL\Exception;
|
|
|
|
class AdminNewsletterController
|
|
{
|
|
public function index()
|
|
{
|
|
if (!isset($_SESSION['admin_id'])) {
|
|
header('Location: /admin/login');
|
|
exit;
|
|
}
|
|
|
|
$connectionParams = [
|
|
'dbname' => getenv('DB_DATABASE') ?: 'freeshop',
|
|
'user' => getenv('DB_USERNAME') ?: 'freeshop_user',
|
|
'password' => getenv('DB_PASSWORD') ?: 'freeshop_password',
|
|
'host' => getenv('DB_HOST') ?: 'db',
|
|
'driver' => 'pdo_mysql',
|
|
'port' => getenv('DB_PORT') ?: 3306,
|
|
'charset' => 'utf8mb4',
|
|
];
|
|
|
|
try {
|
|
$conn = DriverManager::getConnection($connectionParams);
|
|
|
|
// Newsletter-Abonnenten laden
|
|
$stmt = $conn->prepare('
|
|
SELECT n.*, c.first_name, c.last_name, c.email as customer_email
|
|
FROM ws_newsletter n
|
|
LEFT JOIN ws_customer c ON n.customer_id = c.id
|
|
ORDER BY n.created_at DESC
|
|
');
|
|
$stmt->execute();
|
|
$subscribers = $stmt->fetchAllAssociative();
|
|
|
|
// Newsletter-Templates laden
|
|
$stmt = $conn->prepare('SELECT * FROM ws_newsletter_template ORDER BY created_at DESC');
|
|
$stmt->execute();
|
|
$templates = $stmt->fetchAllAssociative();
|
|
|
|
// Statistiken
|
|
$stmt = $conn->prepare('SELECT COUNT(*) as total FROM ws_newsletter WHERE active = 1');
|
|
$stmt->execute();
|
|
$activeSubscribers = $stmt->fetchAssociative()['total'];
|
|
|
|
$stmt = $conn->prepare('SELECT COUNT(*) as total FROM ws_newsletter WHERE active = 0');
|
|
$stmt->execute();
|
|
$inactiveSubscribers = $stmt->fetchAssociative()['total'];
|
|
|
|
$this->render('admin/newsletter/index.html.twig', [
|
|
'title' => 'Webshop Admin - Newsletter-Verwaltung',
|
|
'subscribers' => $subscribers,
|
|
'templates' => $templates,
|
|
'stats' => [
|
|
'active' => $activeSubscribers,
|
|
'inactive' => $inactiveSubscribers,
|
|
'total' => $activeSubscribers + $inactiveSubscribers
|
|
]
|
|
]);
|
|
|
|
} catch (Exception $e) {
|
|
$this->render('admin/newsletter/index.html.twig', [
|
|
'title' => 'Webshop Admin - Newsletter-Verwaltung',
|
|
'error' => 'Datenbankfehler: ' . $e->getMessage()
|
|
]);
|
|
}
|
|
}
|
|
|
|
public function create()
|
|
{
|
|
if (!isset($_SESSION['admin_id'])) {
|
|
header('Location: /admin/login');
|
|
exit;
|
|
}
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
$this->processCreate();
|
|
} else {
|
|
$this->render('admin/newsletter/create.html.twig', [
|
|
'title' => 'Webshop Admin - Newsletter erstellen'
|
|
]);
|
|
}
|
|
}
|
|
|
|
private function processCreate()
|
|
{
|
|
$name = $_POST['name'] ?? '';
|
|
$subject = $_POST['subject'] ?? '';
|
|
$content = $_POST['content'] ?? '';
|
|
$type = $_POST['type'] ?? 'newsletter';
|
|
|
|
if (empty($name) || empty($subject) || empty($content)) {
|
|
$this->render('admin/newsletter/create.html.twig', [
|
|
'title' => 'Webshop Admin - Newsletter erstellen',
|
|
'errors' => ['Alle Felder sind erforderlich'],
|
|
'old' => $_POST
|
|
]);
|
|
return;
|
|
}
|
|
|
|
$connectionParams = [
|
|
'dbname' => getenv('DB_DATABASE') ?: 'freeshop',
|
|
'user' => getenv('DB_USERNAME') ?: 'freeshop_user',
|
|
'password' => getenv('DB_PASSWORD') ?: 'freeshop_password',
|
|
'host' => getenv('DB_HOST') ?: 'db',
|
|
'driver' => 'pdo_mysql',
|
|
'port' => getenv('DB_PORT') ?: 3306,
|
|
'charset' => 'utf8mb4',
|
|
];
|
|
|
|
try {
|
|
$conn = DriverManager::getConnection($connectionParams);
|
|
|
|
$stmt = $conn->prepare('
|
|
INSERT INTO ws_newsletter_template (name, subject, content, type, created_at)
|
|
VALUES (?, ?, ?, ?, NOW())
|
|
');
|
|
$stmt->execute([$name, $subject, $content, $type]);
|
|
|
|
header('Location: /admin/newsletter?success=1');
|
|
exit;
|
|
|
|
} catch (Exception $e) {
|
|
$this->render('admin/newsletter/create.html.twig', [
|
|
'title' => 'Webshop Admin - Newsletter erstellen',
|
|
'errors' => ['Fehler beim Erstellen: ' . $e->getMessage()],
|
|
'old' => $_POST
|
|
]);
|
|
}
|
|
}
|
|
|
|
public function edit($id)
|
|
{
|
|
if (!isset($_SESSION['admin_id'])) {
|
|
header('Location: /admin/login');
|
|
exit;
|
|
}
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
$this->processEdit($id);
|
|
} else {
|
|
$this->loadTemplate($id);
|
|
}
|
|
}
|
|
|
|
private function loadTemplate($id)
|
|
{
|
|
$connectionParams = [
|
|
'dbname' => getenv('DB_DATABASE') ?: 'freeshop',
|
|
'user' => getenv('DB_USERNAME') ?: 'freeshop_user',
|
|
'password' => getenv('DB_PASSWORD') ?: 'freeshop_password',
|
|
'host' => getenv('DB_HOST') ?: 'db',
|
|
'driver' => 'pdo_mysql',
|
|
'port' => getenv('DB_PORT') ?: 3306,
|
|
'charset' => 'utf8mb4',
|
|
];
|
|
|
|
try {
|
|
$conn = DriverManager::getConnection($connectionParams);
|
|
|
|
$stmt = $conn->prepare('SELECT * FROM ws_newsletter_template WHERE id = ?');
|
|
$stmt->execute([$id]);
|
|
$template = $stmt->fetchAssociative();
|
|
|
|
if (!$template) {
|
|
header('Location: /admin/newsletter?error=Template nicht gefunden');
|
|
exit;
|
|
}
|
|
|
|
$this->render('admin/newsletter/edit.html.twig', [
|
|
'title' => 'Webshop Admin - Newsletter bearbeiten',
|
|
'template' => $template
|
|
]);
|
|
|
|
} catch (Exception $e) {
|
|
header('Location: /admin/newsletter?error=' . urlencode($e->getMessage()));
|
|
exit;
|
|
}
|
|
}
|
|
|
|
private function processEdit($id)
|
|
{
|
|
$name = $_POST['name'] ?? '';
|
|
$subject = $_POST['subject'] ?? '';
|
|
$content = $_POST['content'] ?? '';
|
|
$type = $_POST['type'] ?? 'newsletter';
|
|
|
|
if (empty($name) || empty($subject) || empty($content)) {
|
|
$this->render('admin/newsletter/edit.html.twig', [
|
|
'title' => 'Webshop Admin - Newsletter bearbeiten',
|
|
'errors' => ['Alle Felder sind erforderlich'],
|
|
'template' => ['id' => $id] + $_POST
|
|
]);
|
|
return;
|
|
}
|
|
|
|
$connectionParams = [
|
|
'dbname' => getenv('DB_DATABASE') ?: 'freeshop',
|
|
'user' => getenv('DB_USERNAME') ?: 'freeshop_user',
|
|
'password' => getenv('DB_PASSWORD') ?: 'freeshop_password',
|
|
'host' => getenv('DB_HOST') ?: 'db',
|
|
'driver' => 'pdo_mysql',
|
|
'port' => getenv('DB_PORT') ?: 3306,
|
|
'charset' => 'utf8mb4',
|
|
];
|
|
|
|
try {
|
|
$conn = DriverManager::getConnection($connectionParams);
|
|
|
|
$stmt = $conn->prepare('
|
|
UPDATE ws_newsletter_template
|
|
SET name = ?, subject = ?, content = ?, type = ?, updated_at = NOW()
|
|
WHERE id = ?
|
|
');
|
|
$stmt->execute([$name, $subject, $content, $type, $id]);
|
|
|
|
header('Location: /admin/newsletter?success=1');
|
|
exit;
|
|
|
|
} catch (Exception $e) {
|
|
$this->render('admin/newsletter/edit.html.twig', [
|
|
'title' => 'Webshop Admin - Newsletter bearbeiten',
|
|
'errors' => ['Fehler beim Aktualisieren: ' . $e->getMessage()],
|
|
'template' => ['id' => $id] + $_POST
|
|
]);
|
|
}
|
|
}
|
|
|
|
public function delete($id)
|
|
{
|
|
if (!isset($_SESSION['admin_id'])) {
|
|
header('Location: /admin/login');
|
|
exit;
|
|
}
|
|
|
|
$connectionParams = [
|
|
'dbname' => getenv('DB_DATABASE') ?: 'freeshop',
|
|
'user' => getenv('DB_USERNAME') ?: 'freeshop_user',
|
|
'password' => getenv('DB_PASSWORD') ?: 'freeshop_password',
|
|
'host' => getenv('DB_HOST') ?: 'db',
|
|
'driver' => 'pdo_mysql',
|
|
'port' => getenv('DB_PORT') ?: 3306,
|
|
'charset' => 'utf8mb4',
|
|
];
|
|
|
|
try {
|
|
$conn = DriverManager::getConnection($connectionParams);
|
|
|
|
$stmt = $conn->prepare('DELETE FROM ws_newsletter_template WHERE id = ?');
|
|
$stmt->execute([$id]);
|
|
|
|
header('Location: /admin/newsletter?success=1');
|
|
exit;
|
|
|
|
} catch (Exception $e) {
|
|
header('Location: /admin/newsletter?error=' . urlencode($e->getMessage()));
|
|
exit;
|
|
}
|
|
}
|
|
|
|
public function send($id)
|
|
{
|
|
if (!isset($_SESSION['admin_id'])) {
|
|
header('Location: /admin/login');
|
|
exit;
|
|
}
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
$this->processSend($id);
|
|
} else {
|
|
$this->loadSendForm($id);
|
|
}
|
|
}
|
|
|
|
private function loadSendForm($id)
|
|
{
|
|
$connectionParams = [
|
|
'dbname' => getenv('DB_DATABASE') ?: 'freeshop',
|
|
'user' => getenv('DB_USERNAME') ?: 'freeshop_user',
|
|
'password' => getenv('DB_PASSWORD') ?: 'freeshop_password',
|
|
'host' => getenv('DB_HOST') ?: 'db',
|
|
'driver' => 'pdo_mysql',
|
|
'port' => getenv('DB_PORT') ?: 3306,
|
|
'charset' => 'utf8mb4',
|
|
];
|
|
|
|
try {
|
|
$conn = DriverManager::getConnection($connectionParams);
|
|
|
|
// Template laden
|
|
$stmt = $conn->prepare('SELECT * FROM ws_newsletter_template WHERE id = ?');
|
|
$stmt->execute([$id]);
|
|
$template = $stmt->fetchAssociative();
|
|
|
|
if (!$template) {
|
|
header('Location: /admin/newsletter?error=Template nicht gefunden');
|
|
exit;
|
|
}
|
|
|
|
// Abonnenten laden
|
|
$stmt = $conn->prepare('SELECT * FROM ws_newsletter WHERE active = 1');
|
|
$stmt->execute();
|
|
$subscribers = $stmt->fetchAllAssociative();
|
|
|
|
$this->render('admin/newsletter/send.html.twig', [
|
|
'title' => 'Webshop Admin - Newsletter versenden',
|
|
'template' => $template,
|
|
'subscribers' => $subscribers
|
|
]);
|
|
|
|
} catch (Exception $e) {
|
|
header('Location: /admin/newsletter?error=' . urlencode($e->getMessage()));
|
|
exit;
|
|
}
|
|
}
|
|
|
|
private function processSend($id)
|
|
{
|
|
$templateId = $id;
|
|
$testEmail = $_POST['test_email'] ?? '';
|
|
$sendToAll = isset($_POST['send_to_all']);
|
|
$selectedSubscribers = $_POST['subscribers'] ?? [];
|
|
|
|
$connectionParams = [
|
|
'dbname' => getenv('DB_DATABASE') ?: 'freeshop',
|
|
'user' => getenv('DB_USERNAME') ?: 'freeshop_user',
|
|
'password' => getenv('DB_PASSWORD') ?: 'freeshop_password',
|
|
'host' => getenv('DB_HOST') ?: 'db',
|
|
'driver' => 'pdo_mysql',
|
|
'port' => getenv('DB_PORT') ?: 3306,
|
|
'charset' => 'utf8mb4',
|
|
];
|
|
|
|
try {
|
|
$conn = DriverManager::getConnection($connectionParams);
|
|
|
|
// Template laden
|
|
$stmt = $conn->prepare('SELECT * FROM ws_newsletter_template WHERE id = ?');
|
|
$stmt->execute([$templateId]);
|
|
$template = $stmt->fetchAssociative();
|
|
|
|
if (!$template) {
|
|
throw new Exception('Template nicht gefunden');
|
|
}
|
|
|
|
$sentCount = 0;
|
|
$errors = [];
|
|
|
|
if (!empty($testEmail)) {
|
|
// Test-E-Mail senden
|
|
$this->sendNewsletterEmail($template, $testEmail, 'Test Kunde');
|
|
$sentCount++;
|
|
} elseif ($sendToAll) {
|
|
// An alle Abonnenten senden
|
|
$stmt = $conn->prepare('SELECT * FROM ws_newsletter WHERE active = 1');
|
|
$stmt->execute();
|
|
$subscribers = $stmt->fetchAllAssociative();
|
|
|
|
foreach ($subscribers as $subscriber) {
|
|
try {
|
|
$this->sendNewsletterEmail($template, $subscriber['email'], $subscriber['first_name']);
|
|
$sentCount++;
|
|
} catch (Exception $e) {
|
|
$errors[] = 'Fehler bei ' . $subscriber['email'] . ': ' . $e->getMessage();
|
|
}
|
|
}
|
|
} elseif (!empty($selectedSubscribers)) {
|
|
// An ausgewählte Abonnenten senden
|
|
$placeholders = str_repeat('?,', count($selectedSubscribers) - 1) . '?';
|
|
$stmt = $conn->prepare("SELECT * FROM ws_newsletter WHERE id IN ($placeholders) AND active = 1");
|
|
$stmt->execute($selectedSubscribers);
|
|
$subscribers = $stmt->fetchAllAssociative();
|
|
|
|
foreach ($subscribers as $subscriber) {
|
|
try {
|
|
$this->sendNewsletterEmail($template, $subscriber['email'], $subscriber['first_name']);
|
|
$sentCount++;
|
|
} catch (Exception $e) {
|
|
$errors[] = 'Fehler bei ' . $subscriber['email'] . ': ' . $e->getMessage();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Newsletter-Log erstellen
|
|
$stmt = $conn->prepare('
|
|
INSERT INTO ws_newsletter_log (template_id, sent_count, error_count, created_at)
|
|
VALUES (?, ?, ?, NOW())
|
|
');
|
|
$stmt->execute([$templateId, $sentCount, count($errors)]);
|
|
|
|
$message = "Newsletter erfolgreich versendet! $sentCount E-Mails gesendet.";
|
|
if (!empty($errors)) {
|
|
$message .= ' Fehler: ' . implode(', ', $errors);
|
|
}
|
|
|
|
header('Location: /admin/newsletter?success=' . urlencode($message));
|
|
exit;
|
|
|
|
} catch (Exception $e) {
|
|
header('Location: /admin/newsletter?error=' . urlencode($e->getMessage()));
|
|
exit;
|
|
}
|
|
}
|
|
|
|
private function sendNewsletterEmail($template, $email, $firstName)
|
|
{
|
|
$subject = $template['subject'];
|
|
$content = $template['content'];
|
|
|
|
// Platzhalter ersetzen
|
|
$content = str_replace('{{first_name}}', $firstName, $content);
|
|
$content = str_replace('{{email}}', $email, $content);
|
|
$content = str_replace('{{unsubscribe_url}}', '/newsletter/unsubscribe?token=' . bin2hex(random_bytes(16)), $content);
|
|
|
|
$headers = 'MIME-Version: 1.0' . "\r\n";
|
|
$headers .= 'Content-type: text/html; charset=UTF-8' . "\r\n";
|
|
$headers .= 'From: Webshop <noreply@webshop-system.de>' . "\r\n";
|
|
$headers .= 'Reply-To: info@webshop-system.de' . "\r\n";
|
|
$headers .= 'X-Mailer: PHP/' . phpversion();
|
|
|
|
if (!mail($email, $subject, $content, $headers)) {
|
|
throw new Exception('E-Mail konnte nicht gesendet werden');
|
|
}
|
|
}
|
|
|
|
public function subscribers()
|
|
{
|
|
if (!isset($_SESSION['admin_id'])) {
|
|
header('Location: /admin/login');
|
|
exit;
|
|
}
|
|
|
|
$connectionParams = [
|
|
'dbname' => getenv('DB_DATABASE') ?: 'freeshop',
|
|
'user' => getenv('DB_USERNAME') ?: 'freeshop_user',
|
|
'password' => getenv('DB_PASSWORD') ?: 'freeshop_password',
|
|
'host' => getenv('DB_HOST') ?: 'db',
|
|
'driver' => 'pdo_mysql',
|
|
'port' => getenv('DB_PORT') ?: 3306,
|
|
'charset' => 'utf8mb4',
|
|
];
|
|
|
|
try {
|
|
$conn = DriverManager::getConnection($connectionParams);
|
|
|
|
$stmt = $conn->prepare('
|
|
SELECT n.*, c.first_name, c.last_name, c.email as customer_email
|
|
FROM ws_newsletter n
|
|
LEFT JOIN ws_customer c ON n.customer_id = c.id
|
|
ORDER BY n.created_at DESC
|
|
');
|
|
$stmt->execute();
|
|
$subscribers = $stmt->fetchAllAssociative();
|
|
|
|
$this->render('admin/newsletter/subscribers.html.twig', [
|
|
'title' => 'Webshop Admin - Newsletter-Abonnenten',
|
|
'subscribers' => $subscribers
|
|
]);
|
|
|
|
} catch (Exception $e) {
|
|
$this->render('admin/newsletter/subscribers.html.twig', [
|
|
'title' => 'Webshop Admin - Newsletter-Abonnenten',
|
|
'error' => 'Datenbankfehler: ' . $e->getMessage()
|
|
]);
|
|
}
|
|
}
|
|
|
|
public function toggleSubscriber($id)
|
|
{
|
|
if (!isset($_SESSION['admin_id'])) {
|
|
header('Location: /admin/login');
|
|
exit;
|
|
}
|
|
|
|
$connectionParams = [
|
|
'dbname' => getenv('DB_DATABASE') ?: 'freeshop',
|
|
'user' => getenv('DB_USERNAME') ?: 'freeshop_user',
|
|
'password' => getenv('DB_PASSWORD') ?: 'freeshop_password',
|
|
'host' => getenv('DB_HOST') ?: 'db',
|
|
'driver' => 'pdo_mysql',
|
|
'port' => getenv('DB_PORT') ?: 3306,
|
|
'charset' => 'utf8mb4',
|
|
];
|
|
|
|
try {
|
|
$conn = DriverManager::getConnection($connectionParams);
|
|
|
|
$stmt = $conn->prepare('
|
|
UPDATE ws_newsletter
|
|
SET active = NOT active, updated_at = NOW()
|
|
WHERE id = ?
|
|
');
|
|
$stmt->execute([$id]);
|
|
|
|
header('Location: /admin/newsletter/subscribers?success=1');
|
|
exit;
|
|
|
|
} catch (Exception $e) {
|
|
header('Location: /admin/newsletter/subscribers?error=' . urlencode($e->getMessage()));
|
|
exit;
|
|
}
|
|
}
|
|
|
|
protected function render($template, $data = [])
|
|
{
|
|
// Einfache Template-Engine (später durch Twig ersetzen)
|
|
extract($data);
|
|
include __DIR__ . '/../../templates/' . $template;
|
|
}
|
|
}
|