multiShop = new MultiShop(); } /** * Shop-Übersicht */ public function index() { if (!$this->checkAdminSession()) { $this->redirect('/admin/login'); } $shops = $this->multiShop->getAllShops(); $currentShop = $this->multiShop->getCurrentShop(); // Statistiken für jeden Shop $shopStats = []; foreach ($shops as $shop) { $shopStats[$shop['id']] = $this->multiShop->getShopStatistics($shop['id']); } $this->render('admin/shop/index.html.twig', [ 'title' => 'Shop-Verwaltung', 'shops' => $shops, 'current_shop' => $currentShop, 'shop_stats' => $shopStats ]); } /** * Shop erstellen */ public function create() { if (!$this->checkAdminSession()) { $this->redirect('/admin/login'); } if ($_SERVER['REQUEST_METHOD'] === 'POST') { $this->handleShopCreate(); } $this->render('admin/shop/create.html.twig', [ 'title' => 'Neuen Shop erstellen' ]); } /** * Shop bearbeiten */ public function edit($id) { if (!$this->checkAdminSession()) { $this->redirect('/admin/login'); } $shop = $this->multiShop->getShop($id); if (!$shop) { $this->addFlashMessage('Shop nicht gefunden', 'error'); $this->redirect('/admin/shop'); } if ($_SERVER['REQUEST_METHOD'] === 'POST') { $this->handleShopUpdate($id); } $shopConfig = $this->getShopConfiguration($id); $this->render('admin/shop/edit.html.twig', [ 'title' => 'Shop bearbeiten: ' . $shop['name'], 'shop' => $shop, 'shop_config' => $shopConfig ]); } /** * Shop löschen */ public function delete($id) { if (!$this->checkAdminSession()) { $this->redirect('/admin/login'); } $shop = $this->multiShop->getShop($id); if (!$shop) { $this->addFlashMessage('Shop nicht gefunden', 'error'); $this->redirect('/admin/shop'); } if ($shop['is_default']) { $this->addFlashMessage('Standard-Shop kann nicht gelöscht werden', 'error'); $this->redirect('/admin/shop'); } if ($_SERVER['REQUEST_METHOD'] === 'POST') { if ($this->multiShop->deleteShop($id)) { $this->addFlashMessage('Shop erfolgreich gelöscht', 'success'); } else { $this->addFlashMessage('Fehler beim Löschen des Shops', 'error'); } $this->redirect('/admin/shop'); } $this->render('admin/shop/delete.html.twig', [ 'title' => 'Shop löschen: ' . $shop['name'], 'shop' => $shop ]); } /** * Shop-Konfiguration */ public function config($id) { if (!$this->checkAdminSession()) { $this->redirect('/admin/login'); } $shop = $this->multiShop->getShop($id); if (!$shop) { $this->addFlashMessage('Shop nicht gefunden', 'error'); $this->redirect('/admin/shop'); } if ($_SERVER['REQUEST_METHOD'] === 'POST') { $this->handleConfigUpdate($id); } $shopConfig = $this->getShopConfiguration($id); $availableCurrencies = $this->getAvailableCurrencies(); $availableLanguages = $this->getAvailableLanguages(); $availableCountries = $this->getAvailableCountries(); $this->render('admin/shop/config.html.twig', [ 'title' => 'Shop-Konfiguration: ' . $shop['name'], 'shop' => $shop, 'shop_config' => $shopConfig, 'currencies' => $availableCurrencies, 'languages' => $availableLanguages, 'countries' => $availableCountries ]); } /** * Shop-Statistiken */ public function statistics($id) { if (!$this->checkAdminSession()) { $this->redirect('/admin/login'); } $shop = $this->multiShop->getShop($id); if (!$shop) { $this->addFlashMessage('Shop nicht gefunden', 'error'); $this->redirect('/admin/shop'); } $statistics = $this->multiShop->getShopStatistics($id); $recentOrders = $this->getRecentOrders($id); $topProducts = $this->getTopProducts($id); $customerGrowth = $this->getCustomerGrowth($id); $this->render('admin/shop/statistics.html.twig', [ 'title' => 'Shop-Statistiken: ' . $shop['name'], 'shop' => $shop, 'statistics' => $statistics, 'recent_orders' => $recentOrders, 'top_products' => $topProducts, 'customer_growth' => $customerGrowth ]); } /** * Shop-Wechsel */ public function switch($id) { if (!$this->checkAdminSession()) { $this->redirect('/admin/login'); } if ($this->multiShop->switchShop($id)) { $this->addFlashMessage('Shop gewechselt', 'success'); } else { $this->addFlashMessage('Fehler beim Shop-Wechsel', 'error'); } $this->redirect('/admin/shop'); } /** * Shop erstellen verarbeiten */ private function handleShopCreate() { $data = [ 'name' => $_POST['name'] ?? '', 'description' => $_POST['description'] ?? '', 'domain' => $_POST['domain'] ?? '', 'ssl_enabled' => isset($_POST['ssl_enabled']), 'force_ssl' => isset($_POST['force_ssl']), 'active' => isset($_POST['active']), 'sort_order' => intval($_POST['sort_order'] ?? 0) ]; // Validierung if (empty($data['name'])) { $this->addFlashMessage('Shop-Name ist erforderlich', 'error'); return; } if (!empty($data['domain']) && !$this->multiShop->validateShopDomain($data['domain'])) { $this->addFlashMessage('Domain ist bereits vergeben oder ungültig', 'error'); return; } $shopId = $this->multiShop->createShop($data); if ($shopId) { $this->addFlashMessage('Shop erfolgreich erstellt', 'success'); $this->redirect('/admin/shop'); } else { $this->addFlashMessage('Fehler beim Erstellen des Shops', 'error'); } } /** * Shop aktualisieren verarbeiten */ private function handleShopUpdate($id) { $data = [ 'name' => $_POST['name'] ?? '', 'description' => $_POST['description'] ?? '', 'domain' => $_POST['domain'] ?? '', 'ssl_enabled' => isset($_POST['ssl_enabled']), 'force_ssl' => isset($_POST['force_ssl']), 'active' => isset($_POST['active']), 'sort_order' => intval($_POST['sort_order'] ?? 0) ]; // Validierung if (empty($data['name'])) { $this->addFlashMessage('Shop-Name ist erforderlich', 'error'); return; } if (!empty($data['domain']) && !$this->multiShop->validateShopDomain($data['domain'], $id)) { $this->addFlashMessage('Domain ist bereits vergeben oder ungültig', 'error'); return; } if ($this->multiShop->updateShop($id, $data)) { $this->addFlashMessage('Shop erfolgreich aktualisiert', 'success'); $this->redirect('/admin/shop'); } else { $this->addFlashMessage('Fehler beim Aktualisieren des Shops', 'error'); } } /** * Konfiguration aktualisieren */ private function handleConfigUpdate($id) { $configKeys = [ 'SHOP_NAME', 'SHOP_DESCRIPTION', 'SHOP_EMAIL', 'SHOP_PHONE', 'SHOP_ADDRESS', 'SHOP_CITY', 'SHOP_POSTAL_CODE', 'SHOP_COUNTRY', 'SHOP_CURRENCY', 'SHOP_LANGUAGE', 'SHOP_TIMEZONE', 'SHOP_DATE_FORMAT', 'SHOP_TIME_FORMAT', 'SHOP_TAX_RATE', 'SHOP_SHIPPING_COST', 'SHOP_FREE_SHIPPING_THRESHOLD', 'SHOP_MIN_ORDER_AMOUNT', 'SHOP_MAX_ORDER_AMOUNT', 'SHOP_STOCK_WARNING', 'SHOP_REVIEWS_ENABLED', 'SHOP_NEWSLETTER_ENABLED', 'SHOP_MAINTENANCE_MODE', 'SHOP_MAINTENANCE_MESSAGE' ]; foreach ($configKeys as $key) { $value = $_POST[strtolower($key)] ?? ''; $this->multiShop->setShopConfig($key, $value); } $this->addFlashMessage('Shop-Konfiguration aktualisiert', 'success'); $this->redirect("/admin/shop/config/$id"); } /** * Shop-Konfiguration abrufen */ private function getShopConfiguration($shopId) { $config = []; $configKeys = [ 'SHOP_NAME', 'SHOP_DESCRIPTION', 'SHOP_EMAIL', 'SHOP_PHONE', 'SHOP_ADDRESS', 'SHOP_CITY', 'SHOP_POSTAL_CODE', 'SHOP_COUNTRY', 'SHOP_CURRENCY', 'SHOP_LANGUAGE', 'SHOP_TIMEZONE', 'SHOP_DATE_FORMAT', 'SHOP_TIME_FORMAT', 'SHOP_TAX_RATE', 'SHOP_SHIPPING_COST', 'SHOP_FREE_SHIPPING_THRESHOLD', 'SHOP_MIN_ORDER_AMOUNT', 'SHOP_MAX_ORDER_AMOUNT', 'SHOP_STOCK_WARNING', 'SHOP_REVIEWS_ENABLED', 'SHOP_NEWSLETTER_ENABLED', 'SHOP_MAINTENANCE_MODE', 'SHOP_MAINTENANCE_MESSAGE' ]; foreach ($configKeys as $key) { $config[strtolower($key)] = $this->multiShop->getShopConfig($key, ''); } return $config; } /** * Verfügbare Währungen */ private function getAvailableCurrencies() { return [ 'EUR' => 'Euro (€)', 'USD' => 'US Dollar ($)', 'GBP' => 'British Pound (£)', 'CHF' => 'Swiss Franc (CHF)', 'JPY' => 'Japanese Yen (¥)', 'CAD' => 'Canadian Dollar (C$)', 'AUD' => 'Australian Dollar (A$)' ]; } /** * Verfügbare Sprachen */ private function getAvailableLanguages() { return [ 'de' => 'Deutsch', 'en' => 'English', 'fr' => 'Français', 'es' => 'Español', 'it' => 'Italiano', 'nl' => 'Nederlands', 'pl' => 'Polski', 'ru' => 'Русский' ]; } /** * Verfügbare Länder */ private function getAvailableCountries() { try { $stmt = $this->conn->prepare(' SELECT code, name FROM ws_country WHERE active = 1 ORDER BY name ASC '); $stmt->execute(); $countries = $stmt->fetchAllAssociative(); $result = []; foreach ($countries as $country) { $result[$country['code']] = $country['name']; } return $result; } catch (Exception $e) { return [ 'DE' => 'Deutschland', 'AT' => 'Österreich', 'CH' => 'Schweiz', 'US' => 'United States', 'GB' => 'United Kingdom', 'FR' => 'France', 'IT' => 'Italy', 'ES' => 'Spain' ]; } } /** * Letzte Bestellungen */ private function getRecentOrders($shopId) { try { $stmt = $this->conn->prepare(' SELECT o.*, c.first_name, c.last_name FROM ws_order o LEFT JOIN ws_customer c ON o.customer_id = c.id WHERE o.shop_id = ? ORDER BY o.created_at DESC LIMIT 10 '); $stmt->execute([$shopId]); return $stmt->fetchAllAssociative(); } catch (Exception $e) { return []; } } /** * Top-Produkte */ private function getTopProducts($shopId) { try { $stmt = $this->conn->prepare(' SELECT p.*, COUNT(oi.id) as order_count, SUM(oi.quantity) as total_quantity, SUM(oi.price * oi.quantity) as total_revenue FROM ws_product p LEFT JOIN ws_order_item oi ON p.id = oi.product_id LEFT JOIN ws_order o ON oi.order_id = o.id WHERE p.shop_id = ? AND o.status = "completed" GROUP BY p.id ORDER BY total_revenue DESC LIMIT 10 '); $stmt->execute([$shopId]); return $stmt->fetchAllAssociative(); } catch (Exception $e) { return []; } } /** * Kundenwachstum */ private function getCustomerGrowth($shopId) { try { $stmt = $this->conn->prepare(' SELECT DATE(created_at) as date, COUNT(*) as new_customers FROM ws_customer WHERE shop_id = ? AND created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY) GROUP BY DATE(created_at) ORDER BY date ASC '); $stmt->execute([$shopId]); return $stmt->fetchAllAssociative(); } catch (Exception $e) { return []; } } }