src/Controller/AdminProductController.php line 156

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\Product;
  4. use App\Entity\ProductAction;
  5. use App\Entity\ProductImage;
  6. use App\Form\ProductType;
  7. use App\Repository\ProductActionRepository;
  8. use App\Repository\ProductCategoryRepository;
  9. use App\Repository\ProductRepository;
  10. use App\Service\CoverDesignHelper;
  11. use App\Service\ImageUploader;
  12. use Cocur\Slugify\Slugify;
  13. use Doctrine\ORM\EntityManagerInterface;
  14. use Knp\Component\Pager\PaginatorInterface;
  15. use Mobile_Detect;
  16. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  17. use Symfony\Component\HttpFoundation\JsonResponse;
  18. use Symfony\Component\HttpFoundation\RedirectResponse;
  19. use Symfony\Component\HttpFoundation\Request;
  20. use Symfony\Component\HttpFoundation\Response;
  21. use Symfony\Component\Routing\Annotation\Route;
  22. use Twig\Environment;
  23. class AdminProductController extends AbstractController
  24. {
  25.     /**
  26.      * @var EntityManagerInterface
  27.      */
  28.     private $em;
  29.     /**
  30.      *
  31.      * @var PaginatorInterface
  32.      */
  33.     private $paginator;
  34.     /**
  35.      * @var Environment
  36.      */
  37.     private $twig;
  38.     /**
  39.      * @var Mobile_Detect
  40.      */
  41.     private $mobileDetect;
  42.     /**
  43.      * @var CoverDesignHelper
  44.      */
  45.     private $coverDesignHelper;
  46.     public function __constructEntityManagerInterface $emEnvironment $twigPaginatorInterface $paginatorCoverDesignHelper $coverDesignHelper)
  47.     {
  48.         $this->em $em;
  49.         $this->twig $twig// pour ajouter des globals (dispo pour tous les templates)
  50.         $this->paginator $paginator;
  51.         $this->coverDesignHelper $coverDesignHelper;
  52.         // MOBILE DETECT
  53.         $this->mobileDetect = new Mobile_Detect;
  54.         $this->twig->addGlobal('is_mobile'$this->mobileDetect->isMobile());
  55.     }
  56.     /**
  57.      * Listing produits > all products
  58.      * @Route("/admin073/catalogue", name="admin_products_index")
  59.      * @param ProductRepository $productRepository
  60.      * @return Response
  61.      */
  62.     public function adminProductsIndex(ProductRepository $productRepositoryRequest $request)
  63.     {
  64.         $all_products $productRepository->findAll(); // grâce au repo, on fait un select de toutes les entrées
  65.         $count_all_products count($all_products);
  66.         //dump($products);
  67.         // pagination
  68.         $products $this->paginator->paginate($all_products$request->query->getInt('page'1), 3);
  69.         // filtres : action & catégories
  70.         $filters $this->coverDesignHelper->getFilters();
  71.         //dump($filters);
  72.         return $this->render('admin/product/index.html.twig', [
  73.             'products' => $products,
  74.             'filters' => $filters,
  75.             'count_all_products' => $count_all_products,
  76.         ]);
  77.     }
  78.     /**
  79.      * Listing produits filtré : action et catégorie
  80.      * par default les filtres sont sur "all" (id = 0)
  81.      * @Route("/admin073/catalogue/a/{a_slug}/c/{cat_slug}", name="admin_products_filters")
  82.      * @param ProductRepository $productRepository
  83.      * @return Response
  84.      */
  85.     public function adminProductsFiltres(string $a_slugstring $cat_slugProductRepository $productRepositoryProductActionRepository $productActionRepositoryProductCategoryRepository $productCategoryRepositoryRequest $request)
  86.     {
  87.         // filtres : action & catégorie
  88.         // > ex : /admin073/catalogue/a/maintenir/c/tissu
  89.         // > ex : /admin073/catalogue/a/preparer/c/all
  90.         // > ex : /admin073/catalogue/a/all/c/tissu
  91.         // titre à ajouter au compteur, ex: 8 produits >>> dans "maintenir" et "tissu"
  92.         $filter_title['action'] = '';
  93.         $filter_title['category'] = '';
  94.         // get -> action
  95.         if($a_slug != 'all'){
  96.             $get_action $productActionRepository->findOneBy(['slug' => $a_slug]);
  97.             dump($get_action);
  98.             $action['id'] = $get_action->getId();
  99.             $filter_title['action'] = $get_action->getName();
  100.         } else {
  101.             $action['id'] = 0;
  102.         }
  103.         // get -> category
  104.         if($cat_slug != 'all'){
  105.             $get_category $productCategoryRepository->findOneBy(['slug' => $cat_slug]);
  106.             $category['id'] = $get_category->getId();
  107.             $filter_title['category'] = $get_category->getName();
  108.         } else {
  109.             $category['id'] = 0;
  110.         }
  111.         $get_products $productRepository->findByActionAndOrCategory($action['id'], $category['id']);
  112.         // filtres : action & catégories
  113.         $filters $this->coverDesignHelper->getFilters();
  114.         // compteur
  115.         $count_all_products count($get_products);
  116.         // pagination
  117.         $products $this->paginator->paginate($get_products$request->query->getInt('page'1), 6);
  118.         return $this->render('admin/product/index.html.twig', [
  119.             'products' => $products,
  120.             'filters' => $filters,
  121.             'filter_title' => $filter_title,
  122.             'count_all_products' => $count_all_products,
  123.         ]);
  124.     }
  125.     /**
  126.      * Création d'un nouveau produit (product)
  127.      * @Route("/admin073/catalogue/new", name="admin_products_new")
  128.      *
  129.      * @param Request $request
  130.      * @param ImageUploader $imageUploader
  131.      * @return Response
  132.      */
  133.     public function new(request $requestImageUploader $imageUploader)
  134.     {
  135.         $product = new Product(); // on crée une entité
  136.         // formulaire créé externalisé (dossier /form)
  137.         $form $this->createForm(ProductType::class, $product);
  138.         $form->handleRequest($request); // on passe la requête au formulaire (affichera une entité si elle existe par exemple)
  139.         if($form->isSubmitted() && $form->isValid())
  140.         {
  141.             // on insert d'abord le produit en bdd > last_id récupéré pour nommer le dossier photos du produit
  142.             $this->em->persist($product);
  143.             $this->em->flush();
  144.             $last_product_id $product->getId();
  145.             // gestion des images //////////////////////////////////
  146.             // image principale (mainImage)
  147.             // https://www.youtube.com/watch?v=apWjiEuDS0k > 15:44
  148.             $productMainImage $form->get('mainImage')->getData();
  149.             if($productMainImage){
  150.                 // upload file (service perso)
  151.                 $main_image_upload $imageUploader->upload($productMainImage,$last_product_id);
  152.                 // enregistrement main image en bdd
  153.                 $img = new ProductImage();
  154.                 $img->setName($main_image_upload['name'])
  155.                     ->setSize($main_image_upload['size'])
  156.                     ->setIsMain(1); // main image
  157.                 $product->addProductImage($img);
  158.                 // on enregistre la main image du produit
  159.                 $this->em->persist($product);
  160.                 $this->em->flush();
  161.             }
  162.             // galerie d'images
  163.             $productImages $form->get('images')->getData();
  164.             dump($productImages);
  165.             if($productImages){
  166.                 foreach($productImages as $image){
  167.                     // upload file (service perso)
  168.                     $image_upload $imageUploader->upload($image,$last_product_id);
  169.                     // enregistrement chaque image en bdd
  170.                     $img = new ProductImage();
  171.                     $img->setName($image_upload['name'])
  172.                         ->setSize($image_upload['size'])
  173.                         ->setIsMain(0);
  174.                     $product->addProductImage($img);
  175.                 }
  176.                 // on enregistre les images du produit
  177.                 $this->em->persist($product);
  178.                 $this->em->flush();
  179.             }
  180.             // On ajoute une notification au user
  181.             $this->addFlash(
  182.                 'success',
  183.                 "Le produit <strong>{$product->getTitle()}</strong> a bien été enregistré !"
  184.             );
  185.             // on redirige le user
  186.             return $this->redirectToRoute('admin_products_index');
  187.         }
  188.         return $this->render('admin/product/new.html.twig', [
  189.             'product_form' => $form->createView()
  190.         ]);
  191.     }
  192.     /**
  193.      * Edition d'un produit (product)
  194.      * @Route("/admin073/catalogue/{id}/edit", name="admin_products_edit")
  195.      *
  196.      * @param Product $product
  197.      * @param Request $request
  198.      * @param ImageUploader $imageUploader
  199.      * @return Response
  200.      */
  201.     public function edit (Product $productrequest $requestImageUploader $imageUploader)
  202.     {
  203.         // formulaire créé externalisé (dossier /form)
  204.         $form $this->createForm(ProductType::class, $product);
  205.         $form->handleRequest($request); // on passe la requête au formulaire (affichera une entité si elle existe par exemple)
  206.         if($form->isSubmitted() && $form->isValid())
  207.         {
  208.             // on modifie  le produit en bdd
  209.             $this->em->persist($product);
  210.             $this->em->flush();
  211.             $last_product_id $product->getId();
  212.             // gestion des images //////////////////////////////////
  213.             // image principale (mainImage)
  214.             $productMainImage $form->get('mainImage')->getData();
  215.             if($productMainImage){
  216.                 // upload file (service perso)
  217.                 $main_image_upload $imageUploader->upload($productMainImage,$last_product_id);
  218.                 // enregistrement main image en bdd
  219.                 $img = new ProductImage();
  220.                 $img->setName($main_image_upload['name'])
  221.                     ->setSize($main_image_upload['size'])
  222.                     ->setIsMain(1); // main image
  223.                 $product->addProductImage($img);
  224.                 // on enregistre la main image du produit
  225.                 $this->em->persist($product);
  226.                 $this->em->flush();
  227.             }
  228.             // galerie d'images
  229.             $productImages $form->get('images')->getData();
  230.             //dump($productImages);
  231.             if($productImages){
  232.                 foreach($productImages as $image){
  233.                     // upload file (service perso)
  234.                     $image_upload $imageUploader->upload($image,$last_product_id);
  235.                     // enregistrement chaque image en bdd
  236.                     $img = new ProductImage();
  237.                     $img->setName($image_upload['name'])
  238.                         ->setSize($image_upload['size'])
  239.                         ->setIsMain(0);
  240.                     $product->addProductImage($img);
  241.                 }
  242.                 // on enregistre les images du produit
  243.                 $this->em->persist($product);
  244.                 $this->em->flush();
  245.             }
  246.             // On ajoute une notification au user
  247.             $this->addFlash(
  248.                 'success',
  249.                 "Les modifications du produit <strong>{$product->getTitle()}</strong> ont bien été enregistrées !"
  250.             );
  251.             // on redirige le user
  252.             return $this->redirectToRoute('admin_products_index');
  253.         }
  254.         return $this->render('admin/product/edit.html.twig', [
  255.             'product_form' => $form->createView(),
  256.             'product' => $product
  257.         ]);
  258.     }
  259.     /**
  260.      * Suppression d'un produit (en AJAX)
  261.      * @Route("/admin073/catalogue/{id}/delete", name="admin_products_delete", methods={"DELETE"})
  262.      *
  263.      * @param Product $product
  264.      * @param Request $request
  265.      * @return JsonResponse
  266.      */
  267.     public function delete (Product $productrequest $request)
  268.     {
  269.         $data json_decode($request->getContent(), true);
  270.         $product_id $product->getId();
  271.         $product_title $product->getTitle();
  272.         if($this->isCsrfTokenValid('delete'.$product_id$data['_token']))
  273.         {
  274.             // delete fichiers images ?
  275.             $images $product->getProductImages();
  276.             $product_folder $this->getParameter('product_images_directory').$product_id;
  277.             $empty_product_folder 0;
  278.             if($images){
  279.                 foreach ($images as $image){
  280.                     $name $image->getName();
  281.                     $file $product_folder.'/'.$name;
  282.                     // suppression du fichier dans upload/...
  283.                     if(is_file($file) && @unlink($file)){
  284.                         // delete success
  285.                     } else if (is_file ($file)) {
  286.                         // unlink failed.
  287.                         // you would have got an error if it wasn't suppressed
  288.                     } else {
  289.                         // file doesn't exist
  290.                     }
  291.                 }
  292.                 // vérif si le dossier est vide
  293.                 $empty_product_folder $this->coverDesignHelper->isEmptyDir($product_folder);
  294.                 if($empty_product_folder){  // is_empty = true
  295.                     // on kill le dossier de ce produit
  296.                     if (is_dir($product_folder)) {
  297.                         $this->coverDesignHelper->rrmdir($product_folder);
  298.                     }
  299.                 }
  300.             }
  301.             // on supprime le produit de la bdd (et relation action, catégorie)
  302.             $this->em->remove($product);
  303.             $this->em->flush();
  304.             // On ajoute une notification au user
  305.             $this->addFlash(
  306.                 'success',
  307.                 "Le produit <strong>{$product_title}</strong> a été supprimé !"
  308.             );
  309.             // réponse en json
  310.             return new JsonResponse(['success' => 1'folder' => $empty_product_folder]);
  311.         } else {
  312.             // error en json
  313.             return new JsonResponse(['error' => 'Token invalide'], 400);
  314.         }
  315.     }
  316.     /**
  317.      * Suppression d'une image d'un produit (en AJAX)
  318.      * @Route("/admin073/catalogue/delete/image/{id}", name="admin_products_delete_image", methods={"DELETE"})
  319.      *
  320.      * @param ProductImage $productImage
  321.      * @param Request $request
  322.      * @return JsonResponse
  323.      */
  324.     public function delete_image (ProductImage $productImagerequest $request)
  325.     {
  326.         $data json_decode($request->getContent(), true);
  327.         if($this->isCsrfTokenValid('delete'.$productImage->getId(), $data['_token']))
  328.         {
  329.             $name $productImage->getName();
  330.             $productId $productImage->getProduct()->getId();
  331.             // suppression du fichier dans upload/...
  332.             unlink($this->getParameter('product_images_directory').$productId.'/'.$name);
  333.             // suppression de l'image de la bdd
  334.             $this->em->remove($productImage);
  335.             $this->em->flush();
  336.             // réponse en json
  337.             return new JsonResponse(['success' => 1]);
  338.         } else {
  339.             // error en json
  340.             return new JsonResponse(['error' => 'Token invalide'], 400);
  341.         }
  342.     }
  343.     /**
  344.      * !!!! PAS UTILE !!!
  345.      *
  346.      * Affichage d'un seul produit (product) (paramConverter est utilisé ici pour convertir le slug en une entité product avec "Product $product")
  347.      * @Route("/admin073/catalogue/{slug}", name="admin_products_show")
  348.      *
  349.      * @return Response
  350.      */
  351.     public function show(Product $product)
  352.     {
  353.         return $this->render('admin/product/show.html.twig', [
  354.             'product' => $product
  355.         ]);
  356.     }
  357. }