src/Controller/ShopController.php line 272

Open in your IDE?
  1. <?php
  2. # src/Controller/ShopController.php
  3. namespace App\Controller;
  4. use App\Entity\ShopProdukt;
  5. use App\Entity\ShopKategorie;
  6. use App\Entity\Bestellung;
  7. use App\Service\PayPalService;
  8. use App\Service\VPNSetupService;
  9. use App\Repository\ShopProduktRepository;
  10. use App\Repository\ShopKategorieRepository;
  11. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  12. use Symfony\Component\HttpFoundation\Request;
  13. use Symfony\Component\HttpFoundation\Response;
  14. use Symfony\Component\HttpFoundation\JsonResponse;
  15. use Symfony\Component\Routing\Annotation\Route;
  16. use Doctrine\ORM\EntityManagerInterface;
  17. use Symfony\Component\Security\Csrf\CsrfToken;
  18. use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
  19. #[Route('/shop')]
  20. class ShopController extends AbstractController
  21. {
  22.     private ShopProduktRepository $produktRepository;
  23.     private ShopKategorieRepository $kategorieRepository;
  24.     private EntityManagerInterface $entityManager;
  25.     public function __construct(
  26.         ShopProduktRepository $produktRepository,
  27.         ShopKategorieRepository $kategorieRepository,
  28.         EntityManagerInterface $entityManager
  29.     ) {
  30.         $this->produktRepository $produktRepository;
  31.         $this->kategorieRepository $kategorieRepository;
  32.         $this->entityManager $entityManager;
  33.     }
  34.     #[Route('/'name'shop_overview'methods: ['GET'])]
  35.     public function shopOverview(): Response
  36.     {
  37.         // Hole alle Produkte und Kategorien aus der Datenbank
  38.         $products $this->produktRepository->findAll();
  39.         $kategorien $this->kategorieRepository->findAll();
  40.         return $this->render('shop/overview.html.twig', [
  41.             'products' => $products,
  42.             'kategorien' => $kategorien,
  43.         ]);
  44.     }
  45.     #[Route('/product/{id}'name'shop_product_detail'methods: ['GET'])]
  46.     public function productDetail(int $id): Response
  47.     {
  48.         // Suche ein Produkt anhand der ID
  49.         $product $this->produktRepository->find($id);
  50.         if (!$product) {
  51.             throw $this->createNotFoundException('Produkt nicht gefunden');
  52.         }
  53.         return $this->render('shop/detail.html.twig', [
  54.             'product' => $product,
  55.         ]);
  56.     }
  57.     
  58.     
  59.     #[Route('/cart/add/{id}'name'shop_cart_add'methods: ['POST'])]
  60.     public function addToCart(int $idRequest $request): JsonResponse
  61.     {
  62.         $product $this->produktRepository->find($id);
  63.     
  64.         if (!$product) {
  65.             return new JsonResponse(['error' => 'Produkt nicht gefunden'], 404);
  66.         }
  67.     
  68.         // Kasse aus der Session holen
  69.         $session $request->getSession();
  70.         $cart $session->get('cart', []);
  71.     
  72.         // Produkt hinzufügen oder Menge erhöhen
  73.         if (isset($cart[$id])) {
  74.             $cart[$id]['quantity'] += 1;
  75.         } else {
  76.             $cart[$id] = [
  77.                 'product' => $product,
  78.                 'quantity' => 1
  79.             ];
  80.         }
  81.     
  82.         // Warenkorb in der Session speichern
  83.         $session->set('cart'$cart);
  84.     
  85.         return new JsonResponse([
  86.             'cartHtml' => $this->renderView('shop/_cart_items.html.twig', ['cart' => $cart]),
  87.             'total' => $this->calculateTotal($cart),
  88.             'product' => [
  89.                 'name' => $product->getName(),
  90.                 'description' => $product->getBeschreibung(),
  91.                 'price' => number_format($product->getPreis(), 2',''.')
  92.             ]
  93.         ]);
  94.     }
  95.     
  96.     #[Route('/cart/remove/{id}'name'shop_cart_remove'methods: ['POST'])]
  97.     public function removeFromCart(int $idRequest $request): JsonResponse
  98.     {
  99.         try {
  100.             // Kasse aus der Session holen
  101.             $session $request->getSession();
  102.             $cart $session->get('cart', []);
  103.     
  104.             // Entferne das Produkt oder reduziere die Menge
  105.             if (isset($cart[$id])) {
  106.                 if ($cart[$id]['quantity'] > 1) {
  107.                     $cart[$id]['quantity'] -= 1;
  108.                 } else {
  109.                     unset($cart[$id]);
  110.                 }
  111.             }
  112.     
  113.             // Kasse in der Session speichern
  114.             $session->set('cart'$cart);
  115.     
  116.             // Erfolgsnachricht hinzufügen
  117.             $this->addFlash('success''Produkt erfolgreich aus dem Warenkorb entfernt');
  118.     
  119.             return new JsonResponse([
  120.                 'cartHtml' => $this->renderView('shop/_cart_items.html.twig', ['cart' => $cart]),
  121.                 'total' => $this->calculateTotal($cart)
  122.             ]);
  123.         } catch (\Exception $e) {
  124.             // Fehlernachricht hinzufügen
  125.             $this->addFlash('error''Fehler beim Entfernen aus dem Warenkorb');
  126.             return new JsonResponse(['error' => 'Fehler beim Entfernen aus dem Warenkorb'], 500);
  127.         }
  128.     }
  129.   ######################  
  130.     #[Route('/checkout/process'name'shop_checkout_process'methods: ['POST'])]
  131.     public function checkoutProcess(Request $request): Response
  132.     {
  133.         if (!$this->getUser()) {
  134.             $this->addFlash('error''Bitte loggen Sie sich ein, um den Kauf abzuschließen.');
  135.             return $this->redirectToRoute('app_login');
  136.         }
  137.     
  138.         // Hole die Zahlungsmethode aus dem Request (PayPal oder andere Methoden)
  139.         $paymentMethod $request->request->get('payment_method');
  140.     
  141.         // Warenkorb aus der Session holen
  142.         $session $request->getSession();
  143.         $cart $session->get('cart', []);
  144.     
  145.         if (empty($cart)) {
  146.             $this->addFlash('error''Der Warenkorb ist leer.');
  147.             return $this->redirectToRoute('shop_overview');
  148.         }
  149.     
  150.         // Bestellung erstellen
  151.         $bestellung = new Bestellung();
  152.         $bestellung->setKunde($this->getUser());
  153.         $bestellung->setBestelldatum(new \DateTime());
  154.         $bestellung->setStatus('pending');
  155.         $bestellung->setGesamtbetrag($this->calculateTotal($cart));
  156.     
  157.         foreach ($cart as $cartItem) {
  158.             $product $this->produktRepository->find($cartItem['product']->getId());
  159.     
  160.             if (!$product) {
  161.                 throw $this->createNotFoundException('Produkt nicht gefunden.');
  162.             }
  163.     
  164.             $bestellung->addProdukt($product);
  165.         }
  166.     
  167.         $this->entityManager->persist($bestellung);
  168.         $this->entityManager->flush();
  169.     
  170.         // Warenkorb leeren
  171.         $session->remove('cart');
  172.     
  173.         // Weiterleitung zu PayPal oder Stripe basierend auf der Zahlungsmethode
  174.         if ($paymentMethod === 'paypal') {
  175.             return $this->redirectToRoute('paypal_payment', ['order_id' => $bestellung->getId()]);
  176.         } elseif ($paymentMethod === 'stripe') {
  177.             return $this->redirectToRoute('stripe_payment', ['order_id' => $bestellung->getId()]);
  178.         }
  179.     
  180.         // Als Fallback zurück zum Shop, falls keine Methode ausgewählt wurde
  181.         return $this->redirectToRoute('shop_overview');
  182.     }
  183.   
  184.     #[Route('/payment/confirm'name'payment_confirm'methods: ['GET'])]
  185.     public function confirmPayment(Request $requestPayPalService $paypalServiceVPNSetupService $vpnSetupService): Response
  186.     {
  187.         // Abrufen der PayPal-Bestell-ID vom Rückruf von PayPal
  188.         $paypalOrderId $request->query->get('token');  // Abrufen des Tokens aus der PayPal-Rückmeldung
  189.         if (!$paypalOrderId) {
  190.             throw $this->createNotFoundException('PayPal-Token nicht gefunden.');
  191.         }
  192.         // Bestellung anhand der PayPal-Order-ID finden
  193.         $bestellung $this->entityManager->getRepository(Bestellung::class)
  194.             ->findOneBy(['paypalOrderId' => $paypalOrderId]);
  195.         if (!$bestellung) {
  196.             throw $this->createNotFoundException('Bestellung nicht gefunden.');
  197.         }
  198.         // Zahlung bestätigen
  199.         $response $paypalService->captureOrder($paypalOrderId);
  200.         if ($response->statusCode === 201) {
  201.             // Setze den Bestellstatus auf 'completed'
  202.             $bestellung->setStatus('completed');
  203.             $this->entityManager->flush();
  204.             // Hier wird der VPN-Setup-Service aufgerufen
  205.             try {
  206.                 $vpnSetupService->setupVPNForUser($bestellung->getKunde());  // Kunde aus der Bestellung
  207.                 $this->addFlash('success''Zahlung erfolgreich abgeschlossen und VPN eingerichtet!');
  208.             } catch (\Exception $e) {
  209.                 // Wenn das VPN-Setup fehlschlägt, füge eine Fehlermeldung hinzu
  210.                 $this->addFlash('error''Zahlung erfolgreich, aber VPN-Setup fehlgeschlagen.');
  211.             }
  212.             // Erfolgreiche Bestellung anzeigen
  213.             return $this->render('shop/order_success.html.twig', ['order' => $bestellung]);
  214.         }
  215.         // Bei Fehler die Nachricht anzeigen
  216.         $this->addFlash('error''Zahlung fehlgeschlagen.');
  217.         return $this->redirectToRoute('shop_overview');
  218.     }
  219.     #[Route('/payment/paypal/{order_id}'name'paypal_payment')]
  220.     public function paypalPayment(int $order_idPayPalService $paypalService): Response
  221.     {
  222.         // Bestellung aus der Datenbank holen
  223.         $bestellung $this->entityManager->getRepository(Bestellung::class)->find($order_id);
  224.     
  225.         if (!$bestellung) {
  226.             throw $this->createNotFoundException('Bestellung nicht gefunden.');
  227.         }
  228.     
  229.         // Gesamtsumme der Bestellung holen
  230.         $totalAmount $bestellung->getGesamtbetrag();
  231.     
  232.         // PayPal-Order erstellen
  233.         $response $paypalService->createOrder($totalAmount);
  234.     
  235.         // Speichere die PayPal-Order-ID in der Bestellung
  236.         $bestellung->setPaypalOrderId($response->result->id);
  237.         $this->entityManager->flush();
  238.     
  239.         // Leite den Benutzer zur PayPal-Zahlungsseite weiter
  240.         return $this->redirect($response->result->links[1]->href);
  241.     }
  242.     
  243.     
  244.     #[Route('/checkout/{id?}'name'shop_checkout'methods: ['GET''POST'])]
  245.     public function checkout(?int $idRequest $request): Response
  246.     {
  247.         // Warenkorb aus der Session holen
  248.         $session $request->getSession();
  249.         $cart $session->get('cart', []);
  250.     
  251.         // Wenn eine Produkt-ID angegeben ist, behandeln wir es als einzelnes Produkt
  252.         if ($id) {
  253.             $product $this->produktRepository->find($id);
  254.     
  255.             if (!$product) {
  256.                 throw $this->createNotFoundException('Produkt nicht gefunden');
  257.             }
  258.     
  259.             // Füge das Produkt in den Warenkorb hinzu, falls es noch nicht existiert
  260.             if (!isset($cart[$id])) {
  261.                 $cart[$id] = [
  262.                     'product' => $product,
  263.                     'quantity' => 1
  264.                 ];
  265.                 $session->set('cart'$cart);
  266.             }
  267.     
  268.             // Produkte nach Kategorie gruppieren
  269.             $allProducts $this->produktRepository->findAll();
  270.             $similarProducts = [];
  271.             foreach ($allProducts as $similarProduct) {
  272.                 $kategorieId $similarProduct->getKategorie()->getId();
  273.                 if ($kategorieId !== $product->getKategorie()->getId() && !isset($similarProducts[$kategorieId])) {
  274.                     $similarProducts[$kategorieId] = $similarProduct;
  275.                 }
  276.             }
  277.     
  278.             return $this->render('Shop/checkout.html.twig', [
  279.                 'product' => $product,
  280.                 'cart' => $cart,
  281.                 'similar_products' => array_values($similarProducts),
  282.             ]);
  283.         }
  284.     
  285.         // Allgemeiner Checkout, wenn keine ID vorhanden ist
  286.         if (empty($cart)) {
  287.             $this->addFlash('error''Ihr Warenkorb ist leer.');
  288.             return $this->render('Shop/empty_cart.html.twig'); // Ein spezielles Template für leere Warenkörbe
  289.         }
  290.     
  291.         // Gesamtsumme berechnen für den Warenkorb-Checkout
  292.         $total $this->calculateTotal($cart);
  293.     
  294.         return $this->render('Shop/checkout.html.twig', [
  295.             'cart' => $cart,
  296.             'total' => $total,
  297.             'similar_products' => [] // Keine ähnlichen Produkte im allgemeinen Warenkorb-Checkout
  298.         ]);
  299.     }
  300.     private function calculateTotal(array $cart): float
  301.     {
  302.         $total 0;
  303.         foreach ($cart as $item) {
  304.             $total += $item['product']->getPreis() * $item['quantity'];
  305.         }
  306.         return $total// Rückgabe als float
  307.     }
  308.       
  309.     #[Route('/admin/product/update-sort-order'name'admin_shop_product_update_sort_order'methods: ['POST'])]
  310.     public function updateSortOrder(Request $requestCsrfTokenManagerInterface $csrfTokenManager): JsonResponse
  311.     {
  312.         $token $request->request->get('_token');
  313.         if (!$csrfTokenManager->isTokenValid(new CsrfToken('update_sort_order'$token))) {
  314.             return new JsonResponse(['error' => 'Invalid CSRF token'], 400);
  315.         }
  316.         $productId $request->request->get('id');
  317.         $newSortOrder = (int)$request->request->get('sortOrder');
  318.         // Produkt suchen
  319.         $product $this->produktRepository->find($productId);
  320.         if (!$product) {
  321.             return new JsonResponse(['error' => 'Produkt nicht gefunden'], 404);
  322.         }
  323.         // Sortierreihenfolge aktualisieren
  324.         $product->setSortOrder($newSortOrder);
  325.         $this->entityManager->flush();
  326.         return new JsonResponse(['success' => true'message' => 'Sortierreihenfolge erfolgreich aktualisiert']);
  327.     }
  328.     
  329.     
  330.   
  331.     
  332.     
  333.     #[Route('/payment/stripe/{order_id}'name'stripe_payment')]
  334.     public function stripePayment(int $order_id)
  335.     {
  336.         // Logik für Stripe-Zahlung
  337.     }
  338.     
  339. }