<?php
namespace App\Controller;
use App\Aws\SESManager;
use App\Aws\S3Manager;
use App\Entity\Clinic\Clinic;
use App\Entity\Template;
use App\Entity\TemplateLibrary;
use App\Entity\Media\Media;
use App\Services\MediaManager;
use App\Entity\Person\Setting;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Psr\Log\LoggerInterface;
use Doctrine\Persistence\ManagerRegistry;
use App\Form\Model\SearchFilter;
use App\Form\Type\Clinic\SearchFilterType;
use Knp\Component\Pager\PaginatorInterface;
use PDO;
class TemplateController extends AbstractController
{
/**
* @var LoggerInterface
*/
private $logger;
/**
* @var Filesystem
*/
private $filesystem;
/**
* @var string
*/
/**
* @var S3Manager
*/
private $s3Manager;
/**
* @var ManagerRegistry
*/
private $doctrine;
/**
* @var MediaManager
*/
private $mediaManager;
/**
* @var SESManager
*/
private $SESManager;
public function __construct(
SESManager $SESManager,
ManagerRegistry $doctrine,
LoggerInterface $logger,
Filesystem $filesystem,
S3Manager $s3Manager,
MediaManager $mediaManager
) {
$this->doctrine = $doctrine;
$this->logger = $logger;
$this->filesystem = $filesystem;
$this->s3Manager = $s3Manager;
$this->mediaManager = $mediaManager;
$this->SESManager = $SESManager;
date_default_timezone_set('UTC');
}
/**
* @Route("/admin/clinics/{clinic}/templates/{category_id}", name="library", defaults={"category_id"=null})
*/
public function library(Request $request, Clinic $clinic, PaginatorInterface $paginator, $category_id = null) {
$this->denyAccessUnlessGranted('view_external', $clinic);
$category= isset($category_id) && $category_id?$category_id:1;
$data = [];
$data['clinic'] = $clinic;
$filter = new SearchFilter();
$filter->setType($category);
$formSearch = $this->createForm(SearchFilterType::class, $filter);
$formSearch->handleRequest($request);
$results = $paginator->paginate(
$this->getDoctrine()->getRepository(TemplateLibrary::class)->selectTemplatesByFilter($filter),
$request->query->getInt('page', 1),
9
);
$categoryCount = $this->getDoctrine()->getRepository(TemplateLibrary::class)->selectTempCountByCategory($filter);
$categoryArray = (new TemplateLibrary())->allCategory();
$finalCategories = [];
foreach ($categoryArray as $key => $cat) {
$found = false;
foreach ($categoryCount as $catCount) {
if ($key == $catCount['categoryId']) {
$finalCategories[$key] = [
'count' => $catCount['count'],
'name' => $cat,
'id' => $key
];
$found = true;
break;
}
}
if (!$found) {
$finalCategories[$key] = [
'count' => 0,
'name' => $cat,
'id' => $key
];
}
}
// foreach
return $this->render('library/index.html.twig', [
'templates' => $results,
'form_search' => $formSearch->createView(),
'clinic' => $clinic,
'category' => $category,
'finalCategories' => $finalCategories
]);
}
/**
* @Route("/admin/clinics/{clinic}/mytemplates/{category_id}", name="clinic_templates", defaults={"category_id"=null})
*/
public function clinic_templates(Request $request,Clinic $clinic,PaginatorInterface $paginator, $category_id = null){
$this->denyAccessUnlessGranted('view_external', $clinic);
$category= isset($category_id) && $category_id?$category_id:1;
$filter = new SearchFilter();
$filter->setClinic($clinic);
$filter->setType($category);
$formSearch = $this->createForm(SearchFilterType::class, $filter);
$formSearch->handleRequest($request);
$result = $paginator->paginate(
$this->getDoctrine()->getRepository(Template::class)->selectTemplatesByFilter($filter),
$request->query->getInt('page', 1),
9
);
$categoryCount = $this->getDoctrine()->getRepository(Template::class)->selectTempCountByCategory($filter);
$categoryArray = (new TemplateLibrary())->allCategory();
$finalCategories = [];
foreach ($categoryArray as $key => $cat) {
$found = false;
foreach ($categoryCount as $catCount) {
if ($key == $catCount['categoryId']) {
$finalCategories[$key] = [
'count' => $catCount['count'],
'name' => $cat,
'id' => $key
];
$found = true;
break;
}
}
if (!$found) {
$finalCategories[$key] = [
'count' => 0,
'name' => $cat,
'id' => $key
];
}
}
return $this->render('template/list.html.twig', [
'templates' => $result,
'form_search' => $formSearch->createView(),
'clinic' => $clinic,
'category' => $category,
'finalCategories' => $finalCategories
]);
}
/**
* @Route("/admin/clinics/{clinic}/template/{template}", name="temp_index")
*/
public function temp_index(Request $request,Clinic $clinic,Template $template){
$this->denyAccessUnlessGranted('view_external', $clinic);
if($template->getParentId() > 0){
$mainTemplateId = $template->getParentId();
}else{
$mainTemplateId = $template->getId();
}
$allTemplates = $this->getDoctrine()->getRepository(Template::class)->myParentTemplate($mainTemplateId);
if($template->getCategoryId() == 2){
return $this->render('template/reels.html.twig', ['template'=> $template,'clinic'=>$clinic,'allTemplates'=>$allTemplates]);
}else{
return $this->render('template/index.html.twig', ['template'=> $template,'clinic'=>$clinic,'allTemplates'=>$allTemplates]);
}
}
/**
* @Route("/admin/clinics/{clinic}/template/save/{template}", name="temp_save")
*/
public function temp_save(Request $request,Clinic $clinic,Template $template){
$this->denyAccessUnlessGranted('view_external', $clinic);
$entityManager = $this->getDoctrine()->getManager();
if ($template) {
$data = $template->setBody($request->get('content'));
$template->setCss($request->get('css'));
$template->setUpdatedAt(new \DateTime());
$entityManager->flush();
return new JsonResponse(['message' => 'Saved Successfully'],200);
} else {
return new JsonResponse(['status' => 'error', 'message' => 'Website not found'], 404);
}
}
/**
* @Route("/admin/clinics/{clinic}/template/delete/{template}", name="temp_delete")
*/
public function temp_delete(Request $request,Clinic $clinic,Template $template){
$this->denyAccessUnlessGranted('view_external', $clinic);
$entityManager = $this->getDoctrine()->getManager();
if ($template) {
$entityManager->remove($template);
$entityManager->flush();
return new JsonResponse(['message' => 'Deleted Successfully'], 200);
} else {
return new JsonResponse(['status' => 'error', 'message' => 'Website not found'], 404);
}
}
/**
* @Route("/admin/clinics/{clinic}/template/preview/{template}", name="temp_preview")
*/
public function temp_preview(Clinic $clinic,Template $template){
$this->denyAccessUnlessGranted('view_external', $clinic);
return $this->render('template/preview.html.twig', [
'template' => $template,
]);
}
/**
* @Route("/admin/clinics/{clinic}/template/show/{template}", name="temp_show")
*/
public function temp_show(Request $request,Clinic $clinic,Template $template){
$this->denyAccessUnlessGranted('view_external', $clinic);
return new JsonResponse(['html' => $template->getBody(),'css'=>($template->getCss() != '')?$template->getCss():'body {margin: 0;}'],200);
}
/**
* @Route("admin/template/upload-screenshot/{template}", name="temp_upload_ss")
*/
public function uploadScreenshot(Request $request,Template $template){
$file = $request->files->get('screenshot');
if (!$file) {
return new JsonResponse(['status' => 'error', 'message' => 'No file uploaded'], 400);
}
if(isset($file) && $file){
$entityManager = $this->getDoctrine()->getManager();
// $oldBackgroundImg = $user->getMedia();
$fileMimeType = $file->getClientMimeType();
$originalName = $file->getClientOriginalName();
$extension = $file->getClientOriginalExtension();
$uniqueFilename = md5(uniqid()) . time() . '.' . $extension;
$media = new Media();
$media->setFile($file);
$media->setNameFile(Media::getPrefixName($media->getFile()->getClientOriginalName()));
$media->setS3key('users/clinicUsers/' . $uniqueFilename);
$this->s3Manager->upload($media);
if($media->getUrl() != null){
$template->setImage($media->getUrl());
$entityManager->persist($media);
}else{
$filePath = 'uploads/templates/';
// dd($filePath);
$s = $file->move($filePath, $uniqueFilename);
$directory = $this->getParameter('kernel.project_dir') . '/public/uploads/templates/';
$uploadPath = $directory . $uniqueFilename;
$targetFileName = md5(time());
$targetFile = $this->changeFilePermission($uploadPath);
$file = new UploadedFile($targetFile, $uniqueFilename, 'image/png');
$entityManager = $this->getDoctrine()->getManager();
$hasImage = $template->getImage();
$template->setImage($_ENV['APP_URl'].'uploads/templates/'.$uniqueFilename);
}
$entityManager->flush();
return new JsonResponse(['status' => 'success', 'message' => 'Uploaded successfully','data' => ['name'=>$uniqueFilename,'url'=>$template->getImage(),'id'=>$template->getId()]]);
}
}
/**
* @Route("/admin/clinics/{clinic}/templates/{template}/download", name="download_templates")
*/
public function download_templates(Request $request, Clinic $clinic, TemplateLibrary $template)
{
$this->denyAccessUnlessGranted('view_external', $clinic);
$templateId = $template->getTemplateId();
$categoryId = $template->getCategoryId();
$pages = $template->getPages();
// Check if first index file exists
$firstFile = 'library/' . $templateId . '/index.html';
if (!file_exists($firstFile)) {
$this->addFlash('danger', 'Template data not found');
return $this->redirectToRoute('templates', [
'id' => $clinic->getId(),
'category_id' => $categoryId
]);
}
$em = $this->getDoctrine()->getManager();
$parentId = 0;
$templateObjImageUrl = null;
for ($i = 1; $i <= $pages; $i++) {
$filename = 'library/' . $templateId . '/index' . ($i == 1 ? '' : $i) . '.html';
if (!file_exists($filename)) {
$this->addFlash('warning', "Page {$i} not found: $filename");
continue;
}
$htmlContent = file_get_contents($filename);
$templateObj = new Template();
$templateObj->setCategoryId($categoryId);
$templateObj->setParentId($parentId);
$templateObj->setBody($htmlContent);
$templateObj->setTitle($templateId);
$templateObj->setCss(null);
$templateObj->setData($template->getData() ?? null);
$templateObj->setStatus(1);
$templateObj->setClinic($clinic);
$templateObj->setImage(null); // Will be updated after cURL
$templateObj->setCreatedAt(new \DateTime());
$templateObj->setUpdatedAt(new \DateTime());
$em->persist($templateObj);
$em->flush();
if ($parentId === 0) {
$parentId = $templateObj->getId();
}
// Only run cURL once, after saving the first page
try {
$data = [
'template' => $templateObj->getId(),
'library' => $templateId // Adjust if different
];
$ch = curl_init($_ENV['VIDEO_API_URL'] . 'copy_folder.php');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode($data)
]);
$response = curl_exec($ch);
curl_close($ch);
$jsonResponse = json_decode($response, true);
if (!empty($jsonResponse['success'])) {
$templateObjImageUrl = $_ENV['VIDEO_API_URL'] . 'upload/template/' . $templateObj->getId() . '/default-video.mp4';
} else {
throw new \Exception('Folder copy failed.');
}
} catch (\Exception $e) {
$this->addFlash('error', 'Template media copy failed: ' . $e->getMessage());
$em->remove($templateObj);
$em->flush();
return $this->redirectToRoute('templates', [
'id' => $clinic->getId(),
'category_id' => $categoryId
]);
}
// Update image for current page if available
if ($templateObjImageUrl) {
$htmlContent = str_replace('/library/'.$templateId.'/images',$_ENV['VIDEO_API_URL'] . 'upload/template/'.$templateObj->getId().'/images',$htmlContent);
$templateObj->setBody($htmlContent);
$templateObj->setImage($templateObjImageUrl);
$em->persist($templateObj);
$em->flush();
}
}
$this->addFlash('success', 'Template downloaded successfully');
return $this->redirectToRoute('clinic_templates', [
'clinic' => $clinic->getId(),
'category_id' => $categoryId
]);
}
private function changeFilePermission($file)
{
if (!$this->filesystem->exists($file)) {
return false;
}
try {
$this->filesystem->chmod($file, 0777);
} catch (\Exception $e) {
$this->logger->error(
'error change mod for file - ' . $file,
[
'message' => $e->getMessage(),
]
);
return false;
}
return $file;
}
/**
* @Route("/mytemplates/{clinic}", name="my_templates")
*/
public function my_templates(Clinic $clinic)
{
$images = [];
try{
$myTemplates = $this->getDoctrine()->getRepository(Template::class)->findBy(['clinic' => $clinic]);
foreach ($myTemplates as $template)
{
$images[] = [
'media_url' => $template->getImage(),
'id' => $template->getId(),
'category'=>$template->getCategoryId()
];
}
}catch(\Exception $e){}
return new JsonResponse(['images' => $images],200);
}
/**
* @Route("/mytemplates/images/create", name="my_templates_imagecreate")
*/
public function my_templates_imagecreate(Request $request)
{
try {
$data = json_decode(file_get_contents('php://input'), true);
$ch = curl_init($_ENV['VIDEO_API_URL'] . 'image.php');
if(isset($data['image']) && $data['image']){
$data['image'] = str_replace($_ENV['VIDEO_API_URL'].'upload','',$data['image']);
}
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode($data)
]);
$response = curl_exec($ch);
if (curl_errno($ch)) {
return new Response("cURL Error: " . curl_error($ch), 500);
}
curl_close($ch);
return new JsonResponse($response);
} catch (\Exception $e) {
return new JsonResponse(['status' => 0, 'message' => $e->getMessage()]);
}
}
/**
* @Route("/admin/mytemplates/reels/edit", name="my_templates_reelsedit")
*/
public function my_templates_reelsedit(Request $request)
{
$data = json_decode(file_get_contents('php://input'), true);
$clinic = $this->getDoctrine()->getRepository(Clinic::class)->find($data['myclinic']);
$this->denyAccessUnlessGranted('view_external', $clinic);
$template = $this->getDoctrine()->getRepository(Template::class)->find($data['mytemplate']);
if(!$template){
return new JsonResponse(['status' => 0, 'message' => 'Template not found']);
}
$doc = new \DOMDocument();
libxml_use_internal_errors(true);
$doc->loadHTML($template->getBody(), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
libxml_clear_errors();
$videoContainer = (new \DOMXPath($doc))->query('//div[@id="video-container"]')->item(0);
if ($videoContainer) {
while ($videoContainer->firstChild) {
$videoContainer->removeChild($videoContainer->firstChild);
}
$tmpDoc = new \DOMDocument();
$tmpDoc->loadHTML('<div>' . $data['body'] . '</div>', LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
foreach ($tmpDoc->documentElement->childNodes as $child) {
$videoContainer->appendChild($doc->importNode($child, true));
}
}
$template->setData(json_encode($data['templateData'] ?? []));
// $template->setBody($doc->saveHTML());
$em = $this->getDoctrine()->getManager();
try {
$videoCh = curl_init($_ENV['VIDEO_API_URL'] . 'video.php');
$videoData = [
'textImages' => $data['textImages'],
'videoPath' => 'upload/template/'.$template->getId().'/bg-video.mp4',
'template'=>$data['mytemplate']
];
curl_setopt_array($videoCh, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode($videoData)
]);
$response = curl_exec($videoCh);
$videoResponse = json_decode($response, true);
curl_close($videoCh);
if ($videoResponse['success'] ?? false) {
// $template->setImage($videoResponse['downloadUrl']);
// $em->persist($template);
// $em->flush();
}
$em->persist($template);
$em->flush();
return new JsonResponse($videoResponse);
} catch (\Exception $e) {
return new JsonResponse(['status' => 0, 'message' => $e->getMessage()]);
}
}
}