src/Controller/TemplateController.php line 196

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Aws\SESManager;
  4. use App\Aws\S3Manager;
  5. use App\Entity\Clinic\Clinic;
  6. use App\Entity\Template;
  7. use App\Entity\TemplateLibrary;
  8. use App\Entity\Media\Media;
  9. use App\Services\MediaManager;
  10. use App\Entity\Person\Setting;
  11. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  12. use Symfony\Component\HttpFoundation\JsonResponse;
  13. use Symfony\Component\HttpFoundation\Request;
  14. use Symfony\Component\HttpFoundation\Response;
  15. use Symfony\Component\Routing\Annotation\Route;
  16. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  17. use Symfony\Component\Filesystem\Filesystem;
  18. use Symfony\Component\HttpFoundation\File\UploadedFile;
  19. use Psr\Log\LoggerInterface;
  20. use Doctrine\Persistence\ManagerRegistry;
  21. use App\Form\Model\SearchFilter;
  22. use App\Form\Type\Clinic\SearchFilterType;
  23. use Knp\Component\Pager\PaginatorInterface;
  24. use PDO;
  25. class TemplateController extends AbstractController
  26. {
  27.      /**
  28.      * @var LoggerInterface
  29.      */
  30.     private $logger;
  31.     /**
  32.      * @var Filesystem
  33.      */
  34.     private $filesystem;
  35.         /**
  36.      * @var string
  37.      */
  38.     /**
  39.      * @var S3Manager
  40.      */
  41.     private $s3Manager;
  42.        /**
  43.      * @var ManagerRegistry
  44.      */
  45.     private $doctrine;
  46.      /**
  47.      * @var MediaManager
  48.      */
  49.     private $mediaManager;
  50.     /**
  51.      * @var SESManager
  52.      */
  53.     private $SESManager;
  54.     public function __construct(
  55.         SESManager $SESManager,
  56.         ManagerRegistry $doctrine,
  57.         LoggerInterface $logger,
  58.         Filesystem $filesystem,
  59.         S3Manager $s3Manager,
  60.         MediaManager $mediaManager
  61.     ) {
  62.         $this->doctrine $doctrine;
  63.         $this->logger $logger;
  64.         $this->filesystem $filesystem;
  65.         $this->s3Manager $s3Manager;
  66.         $this->mediaManager $mediaManager;
  67.         $this->SESManager $SESManager;
  68.         date_default_timezone_set('UTC');
  69.     }
  70.     /**
  71.      * @Route("/admin/clinics/{clinic}/templates/{category_id}", name="library", defaults={"category_id"=null})
  72.      */
  73.     public function library(Request $requestClinic $clinicPaginatorInterface $paginator$category_id null) {
  74.         $this->denyAccessUnlessGranted('view_external'$clinic);
  75.         $category= isset($category_id) && $category_id?$category_id:1;
  76.         $data = [];
  77.         $data['clinic'] = $clinic;
  78.         $filter = new SearchFilter();
  79.         $filter->setType($category);
  80.         $formSearch $this->createForm(SearchFilterType::class, $filter);
  81.         $formSearch->handleRequest($request);
  82.         $results $paginator->paginate(
  83.             $this->getDoctrine()->getRepository(TemplateLibrary::class)->selectTemplatesByFilter($filter),
  84.             $request->query->getInt('page'1),
  85.             9
  86.         );
  87.         $categoryCount $this->getDoctrine()->getRepository(TemplateLibrary::class)->selectTempCountByCategory($filter);
  88.         $categoryArray = (new TemplateLibrary())->allCategory();
  89.         $finalCategories = [];
  90.         foreach ($categoryArray as $key => $cat) {
  91.             $found false;
  92.             foreach ($categoryCount as $catCount) {
  93.                 if ($key == $catCount['categoryId']) {
  94.                     $finalCategories[$key] = [
  95.                         'count' => $catCount['count'],
  96.                         'name' => $cat,
  97.                         'id' => $key
  98.                     ];
  99.                     $found true;
  100.                     break;
  101.                 }
  102.             }
  103.             if (!$found) {
  104.                 $finalCategories[$key] = [
  105.                     'count' => 0,
  106.                     'name' => $cat,
  107.                     'id' => $key
  108.                 ];
  109.             }
  110.         }
  111.       //  foreach
  112.         
  113.         return $this->render('library/index.html.twig', [
  114.             'templates' => $results,
  115.             'form_search' => $formSearch->createView(),
  116.             'clinic' => $clinic,
  117.             'category' => $category,
  118.             'finalCategories' => $finalCategories
  119.         ]);
  120.      }
  121.     
  122.      /**
  123.      * @Route("/admin/clinics/{clinic}/mytemplates/{category_id}", name="clinic_templates", defaults={"category_id"=null})
  124.      */     
  125.     public function clinic_templates(Request $request,Clinic $clinic,PaginatorInterface $paginator$category_id null){
  126.         $this->denyAccessUnlessGranted('view_external'$clinic);
  127.         $category= isset($category_id) && $category_id?$category_id:1;
  128.         $filter = new SearchFilter();
  129.         $filter->setClinic($clinic);
  130.         $filter->setType($category);
  131.         $formSearch $this->createForm(SearchFilterType::class, $filter);
  132.         $formSearch->handleRequest($request);
  133.         $result $paginator->paginate(
  134.             $this->getDoctrine()->getRepository(Template::class)->selectTemplatesByFilter($filter),
  135.             $request->query->getInt('page'1),
  136.             9
  137.         );
  138.         $categoryCount $this->getDoctrine()->getRepository(Template::class)->selectTempCountByCategory($filter);
  139.         $categoryArray = (new TemplateLibrary())->allCategory();
  140.         $finalCategories = [];
  141.         foreach ($categoryArray as $key => $cat) {
  142.             $found false;
  143.             foreach ($categoryCount as $catCount) {
  144.                 if ($key == $catCount['categoryId']) {
  145.                     $finalCategories[$key] = [
  146.                         'count' => $catCount['count'],
  147.                         'name' => $cat,
  148.                         'id' => $key
  149.                     ];
  150.                     $found true;
  151.                     break;
  152.                 }
  153.             }
  154.             if (!$found) {
  155.                 $finalCategories[$key] = [
  156.                     'count' => 0,
  157.                     'name' => $cat,
  158.                     'id' => $key
  159.                 ];
  160.             }
  161.         }
  162.          return $this->render('template/list.html.twig', [
  163.           'templates' => $result,
  164.             'form_search' => $formSearch->createView(),
  165.             'clinic' => $clinic,
  166.             'category' => $category,
  167.             'finalCategories' => $finalCategories
  168.         ]);
  169.     }
  170.    /**
  171.      * @Route("/admin/clinics/{clinic}/template/{template}", name="temp_index")
  172.      */     
  173.     public function temp_index(Request $request,Clinic $clinic,Template $template){
  174.         $this->denyAccessUnlessGranted('view_external'$clinic);
  175.         if($template->getParentId() > 0){
  176.             $mainTemplateId $template->getParentId();
  177.         }else{
  178.             $mainTemplateId $template->getId();
  179.         }
  180.         $allTemplates $this->getDoctrine()->getRepository(Template::class)->myParentTemplate($mainTemplateId);
  181.         if($template->getCategoryId() == 2){
  182.             
  183.         return $this->render('template/reels.html.twig',  ['template'=> $template,'clinic'=>$clinic,'allTemplates'=>$allTemplates]);
  184.         }else{
  185.         return $this->render('template/index.html.twig',  ['template'=> $template,'clinic'=>$clinic,'allTemplates'=>$allTemplates]);
  186.         }
  187.     }
  188.     /**
  189.      * @Route("/admin/clinics/{clinic}/template/save/{template}", name="temp_save")
  190.      */  
  191.      public function temp_save(Request $request,Clinic $clinic,Template $template){
  192.         $this->denyAccessUnlessGranted('view_external'$clinic);
  193.         $entityManager $this->getDoctrine()->getManager();
  194.         if ($template) {
  195.             $data $template->setBody($request->get('content'));
  196.             $template->setCss($request->get('css'));
  197.             $template->setUpdatedAt(new \DateTime());
  198.             $entityManager->flush();
  199.             return new JsonResponse(['message' => 'Saved Successfully'],200);
  200.         } else {
  201.             return new JsonResponse(['status' => 'error''message' => 'Website not found'], 404);
  202.         }
  203.     }
  204.   /**
  205.      * @Route("/admin/clinics/{clinic}/template/delete/{template}", name="temp_delete")
  206.      */  
  207.      public function temp_delete(Request $request,Clinic $clinic,Template $template){
  208.         $this->denyAccessUnlessGranted('view_external'$clinic);
  209.         $entityManager $this->getDoctrine()->getManager();
  210.         if ($template) {
  211.             $entityManager->remove($template);
  212.             $entityManager->flush();
  213.             return new JsonResponse(['message' => 'Deleted Successfully'], 200);
  214.         } else {
  215.             return new JsonResponse(['status' => 'error''message' => 'Website not found'], 404);
  216.         }
  217.     }
  218.     
  219.     
  220.      /**
  221.      * @Route("/admin/clinics/{clinic}/template/preview/{template}", name="temp_preview")
  222.      */  
  223.      public function temp_preview(Clinic $clinic,Template $template){
  224.         $this->denyAccessUnlessGranted('view_external'$clinic);
  225.       return $this->render('template/preview.html.twig', [
  226.                 'template' => $template,
  227.             ]);
  228.     }
  229.     /**
  230.      * @Route("/admin/clinics/{clinic}/template/show/{template}", name="temp_show")
  231.      */  
  232.      public function temp_show(Request $request,Clinic $clinic,Template $template){
  233.         
  234.         $this->denyAccessUnlessGranted('view_external'$clinic);
  235.         return new JsonResponse(['html' => $template->getBody(),'css'=>($template->getCss() != '')?$template->getCss():'body {margin: 0;}'],200);
  236.     }
  237.     /**
  238.      * @Route("admin/template/upload-screenshot/{template}", name="temp_upload_ss")
  239.      */  
  240.      public function uploadScreenshot(Request $request,Template $template){    
  241.     $file $request->files->get('screenshot');
  242.     if (!$file) {
  243.         return new JsonResponse(['status' => 'error''message' => 'No file uploaded'], 400);
  244.     }
  245.      if(isset($file) && $file){
  246.                 $entityManager $this->getDoctrine()->getManager();
  247.             // $oldBackgroundImg = $user->getMedia();
  248.             $fileMimeType $file->getClientMimeType();
  249.             $originalName $file->getClientOriginalName();
  250.             $extension $file->getClientOriginalExtension();
  251.             $uniqueFilename md5(uniqid()) . time() . '.' $extension;
  252.        
  253.             $media = new Media();
  254.             $media->setFile($file);
  255.             $media->setNameFile(Media::getPrefixName($media->getFile()->getClientOriginalName()));
  256.             $media->setS3key('users/clinicUsers/' $uniqueFilename);
  257.              $this->s3Manager->upload($media);
  258.              if($media->getUrl() != null){
  259.                 $template->setImage($media->getUrl());
  260.                 $entityManager->persist($media);
  261.              }else{
  262.                 $filePath 'uploads/templates/';
  263.                 // dd($filePath);
  264.                 $s =  $file->move($filePath$uniqueFilename);
  265.            
  266.             $directory $this->getParameter('kernel.project_dir') . '/public/uploads/templates/';
  267.             $uploadPath $directory $uniqueFilename;
  268.             $targetFileName md5(time());
  269.             $targetFile $this->changeFilePermission($uploadPath);
  270.             $file = new UploadedFile($targetFile$uniqueFilename'image/png');
  271.              $entityManager $this->getDoctrine()->getManager();
  272.              $hasImage $template->getImage();
  273.           
  274.                 $template->setImage($_ENV['APP_URl'].'uploads/templates/'.$uniqueFilename);
  275.              }
  276.              $entityManager->flush();
  277.              
  278.             return new JsonResponse(['status' => 'success''message' => 'Uploaded successfully','data' => ['name'=>$uniqueFilename,'url'=>$template->getImage(),'id'=>$template->getId()]]);
  279.         }
  280.     
  281.      }
  282.      /**
  283.      * @Route("/admin/clinics/{clinic}/templates/{template}/download", name="download_templates")
  284.      */ 
  285.     public function download_templates(Request $requestClinic $clinicTemplateLibrary $template)
  286.     {
  287.         $this->denyAccessUnlessGranted('view_external'$clinic);
  288.         $templateId $template->getTemplateId();
  289.         $categoryId $template->getCategoryId();
  290.         $pages $template->getPages();
  291.         // Check if first index file exists
  292.         $firstFile 'library/' $templateId '/index.html';
  293.         if (!file_exists($firstFile)) {
  294.             $this->addFlash('danger''Template data not found');
  295.             return $this->redirectToRoute('templates', [
  296.                 'id' => $clinic->getId(),
  297.                 'category_id' => $categoryId
  298.             ]);
  299.         }
  300.         $em $this->getDoctrine()->getManager();
  301.         $parentId 0;
  302.         $templateObjImageUrl null;
  303.         for ($i 1$i <= $pages$i++) {
  304.             $filename 'library/' $templateId '/index' . ($i == '' $i) . '.html';
  305.             if (!file_exists($filename)) {
  306.                 $this->addFlash('warning'"Page {$i} not found: $filename");
  307.                 continue;
  308.             }
  309.             $htmlContent file_get_contents($filename);
  310.             $templateObj = new Template();
  311.             $templateObj->setCategoryId($categoryId);
  312.             $templateObj->setParentId($parentId);
  313.             $templateObj->setBody($htmlContent);
  314.             $templateObj->setTitle($templateId);
  315.             $templateObj->setCss(null);
  316.             $templateObj->setData($template->getData() ?? null);
  317.             $templateObj->setStatus(1);
  318.             $templateObj->setClinic($clinic);
  319.             $templateObj->setImage(null); // Will be updated after cURL
  320.             $templateObj->setCreatedAt(new \DateTime());
  321.             $templateObj->setUpdatedAt(new \DateTime());
  322.             $em->persist($templateObj);
  323.             $em->flush();
  324.             if ($parentId === 0) {
  325.                 $parentId $templateObj->getId();
  326.             }
  327.             // Only run cURL once, after saving the first page
  328.                 try {
  329.                     $data = [
  330.                         'template' => $templateObj->getId(),
  331.                         'library' => $templateId // Adjust if different
  332.                     ];
  333.                     $ch curl_init($_ENV['VIDEO_API_URL'] . 'copy_folder.php');
  334.                     curl_setopt_array($ch, [
  335.                         CURLOPT_RETURNTRANSFER => true,
  336.                         CURLOPT_POST => true,
  337.                         CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
  338.                         CURLOPT_POSTFIELDS => json_encode($data)
  339.                     ]);
  340.                     $response curl_exec($ch);
  341.                     curl_close($ch);
  342.                     $jsonResponse json_decode($responsetrue);
  343.                     if (!empty($jsonResponse['success'])) {
  344.                         $templateObjImageUrl $_ENV['VIDEO_API_URL'] . 'upload/template/' $templateObj->getId() . '/default-video.mp4';
  345.                     } else {
  346.                         throw new \Exception('Folder copy failed.');
  347.                     }
  348.                 } catch (\Exception $e) {
  349.                     $this->addFlash('error''Template media copy failed: ' $e->getMessage());
  350.                     $em->remove($templateObj);
  351.                     $em->flush();
  352.                     return $this->redirectToRoute('templates', [
  353.                         'id' => $clinic->getId(),
  354.                         'category_id' => $categoryId
  355.                     ]);
  356.                 }
  357.             
  358.             // Update image for current page if available
  359.             if ($templateObjImageUrl) {
  360.                 $htmlContent str_replace('/library/'.$templateId.'/images',$_ENV['VIDEO_API_URL'] . 'upload/template/'.$templateObj->getId().'/images',$htmlContent);
  361.                 $templateObj->setBody($htmlContent);
  362.                 $templateObj->setImage($templateObjImageUrl);
  363.                 $em->persist($templateObj);
  364.                 $em->flush();
  365.             }
  366.         }
  367.         $this->addFlash('success''Template downloaded successfully');
  368.         return $this->redirectToRoute('clinic_templates', [
  369.             'clinic' => $clinic->getId(),
  370.             'category_id' => $categoryId
  371.         ]);
  372.     }
  373.      private function changeFilePermission($file)
  374.     {
  375.         if (!$this->filesystem->exists($file)) {
  376.             return false;
  377.         }
  378.         try {
  379.             $this->filesystem->chmod($file0777);
  380.         } catch (\Exception $e) {
  381.             $this->logger->error(
  382.                 'error change mod for file - ' $file,
  383.                 [
  384.                     'message' => $e->getMessage(),
  385.                 ]
  386.             );
  387.             return false;
  388.         }
  389.         return $file;
  390.     } 
  391.     
  392.      /**
  393.      * @Route("/mytemplates/{clinic}", name="my_templates")
  394.      */
  395.     public function my_templates(Clinic $clinic)
  396.     {
  397.         $images = [];
  398.         try{
  399.             $myTemplates $this->getDoctrine()->getRepository(Template::class)->findBy(['clinic' => $clinic]);
  400.             foreach ($myTemplates as $template)
  401.             {
  402.                 $images[] = [
  403.                     'media_url' => $template->getImage(),
  404.                     'id' => $template->getId(),
  405.                     'category'=>$template->getCategoryId()
  406.                 ];
  407.             }
  408.            }catch(\Exception $e){}
  409.     
  410.         return new JsonResponse(['images' => $images],200);
  411.     }
  412.     /**
  413.      * @Route("/mytemplates/images/create", name="my_templates_imagecreate")
  414.      */
  415.     public function my_templates_imagecreate(Request $request)
  416.     {
  417.         try {
  418.             $data json_decode(file_get_contents('php://input'), true);
  419.             $ch curl_init($_ENV['VIDEO_API_URL'] . 'image.php');
  420.             if(isset($data['image']) && $data['image']){
  421.                 $data['image']  = str_replace($_ENV['VIDEO_API_URL'].'upload','',$data['image']);
  422.             }
  423.             curl_setopt_array($ch, [
  424.                 CURLOPT_RETURNTRANSFER => true,
  425.                 CURLOPT_POST => true,
  426.                 CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
  427.                 CURLOPT_POSTFIELDS => json_encode($data)
  428.             ]);
  429.             $response curl_exec($ch);
  430.             if (curl_errno($ch)) {
  431.                 return new Response("cURL Error: " curl_error($ch), 500);
  432.             }
  433.             curl_close($ch);
  434.             return new JsonResponse($response);
  435.         } catch (\Exception $e) {
  436.             return new JsonResponse(['status' => 0'message' => $e->getMessage()]);
  437.         }
  438.     }
  439.     /**
  440.  * @Route("/admin/mytemplates/reels/edit", name="my_templates_reelsedit")
  441.  */
  442. public function my_templates_reelsedit(Request $request)
  443. {
  444.     $data json_decode(file_get_contents('php://input'), true);
  445.     $clinic $this->getDoctrine()->getRepository(Clinic::class)->find($data['myclinic']);
  446.     $this->denyAccessUnlessGranted('view_external'$clinic);
  447.     $template $this->getDoctrine()->getRepository(Template::class)->find($data['mytemplate']);
  448.     if(!$template){
  449.         return new JsonResponse(['status' => 0'message' => 'Template not found']);
  450.     }
  451.     $doc = new \DOMDocument();
  452.     libxml_use_internal_errors(true);
  453.     $doc->loadHTML($template->getBody(), LIBXML_HTML_NOIMPLIED LIBXML_HTML_NODEFDTD);
  454.     libxml_clear_errors();
  455.     $videoContainer = (new \DOMXPath($doc))->query('//div[@id="video-container"]')->item(0);
  456.     if ($videoContainer) {
  457.         while ($videoContainer->firstChild) {
  458.             $videoContainer->removeChild($videoContainer->firstChild);
  459.         }
  460.         $tmpDoc = new \DOMDocument();
  461.         $tmpDoc->loadHTML('<div>' $data['body'] . '</div>'LIBXML_HTML_NOIMPLIED LIBXML_HTML_NODEFDTD);
  462.         foreach ($tmpDoc->documentElement->childNodes as $child) {
  463.             $videoContainer->appendChild($doc->importNode($childtrue));
  464.         }
  465.     }
  466.     $template->setData(json_encode($data['templateData'] ?? []));
  467.     // $template->setBody($doc->saveHTML());
  468.     $em $this->getDoctrine()->getManager();
  469.     try {
  470.             $videoCh curl_init($_ENV['VIDEO_API_URL'] . 'video.php');
  471.             $videoData = [
  472.                 'textImages' => $data['textImages'],
  473.                 'videoPath' => 'upload/template/'.$template->getId().'/bg-video.mp4',
  474.                 'template'=>$data['mytemplate']
  475.             ];
  476.             curl_setopt_array($videoCh, [
  477.                 CURLOPT_RETURNTRANSFER => true,
  478.                 CURLOPT_POST => true,
  479.                 CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
  480.                 CURLOPT_POSTFIELDS => json_encode($videoData)
  481.             ]);
  482.             $response curl_exec($videoCh);
  483.             $videoResponse json_decode($responsetrue);
  484.             curl_close($videoCh);
  485.             if ($videoResponse['success'] ?? false) {
  486.                 // $template->setImage($videoResponse['downloadUrl']);
  487.                 // $em->persist($template);
  488.                 // $em->flush();
  489.             }
  490.             $em->persist($template);
  491.             $em->flush();
  492.             return new JsonResponse($videoResponse);
  493.         
  494.     } catch (\Exception $e) {
  495.         return new JsonResponse(['status' => 0'message' => $e->getMessage()]);
  496.     }
  497. }   
  498. }