src/Controller/Backend/DashboardListController.php line 31

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Backend;
  3. use App\Controller\Base\BaseController;
  4. use App\Entity\DashboardList;
  5. use App\Entity\DashboardTab;
  6. use App\Entity\TGrafik;
  7. use App\Filter\DashboardListFilterType;
  8. use App\Form\DashboardListType;
  9. use App\Repository\DashboardComponentRepository;
  10. use App\Repository\DashboardListRepository;
  11. use App\Repository\TGrafikRepository;
  12. use Symfony\Component\Routing\Annotation\Route;
  13. use Kematjaya\Breadcrumb\Lib\Builder as BreacrumbBuilder;
  14. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  15. use App\Utils\ObjectManager;
  16. use Doctrine\ORM\EntityManagerInterface;
  17. use Symfony\Component\HttpFoundation\Request;
  18. use Knp\Component\Pager\PaginatorInterface;
  19. use Symfony\Component\HttpFoundation\JsonResponse;
  20. class DashboardListController extends BaseController
  21. {
  22.     private $pageName 'dashboard_list';
  23.     private $class DashboardList::class;
  24.     /**
  25.      * @Route("/dashboard_list",name="dashboard_list")
  26.      */
  27.     public function index(BreacrumbBuilder $builderRequest $requestPaginatorInterface $paginatorInterface)
  28.     {
  29.         $builder->add('Setting Dashboard '"dashboard_list", array(), "&nbsp;<i class='fa fa-home'></i>");
  30.         $form $this->createFormFilter(DashboardListFilterType::class);
  31.         $queryBuilder $this->getQueryBuilder($this->class);
  32.         $queryBuilder $this->buildFilter($request$form$queryBuilder)->addOrderBy("this.id""DESC");
  33.         $this->setSessionLimit($request);
  34.         $maxPerPage $request->getSession()->get("limit") ? $request->getSession()->get("limit") : $this->getLimit();
  35.         $pagination $paginatorInterface->paginate($queryBuilder$request->query->getInt('page'1), $maxPerPage);
  36.         return $this->render('backend/dashboard_list/index.html.twig', [
  37.             'page_name' => $this->pageName,
  38.             'button_credential' => $this->buttonCredentials($this->pageName),
  39.             'filter' => $form->createView(),
  40.             'pagination' => $pagination
  41.         ]);
  42.     }
  43.     /**
  44.      * @Route("/dashboard_list/form/{id}", defaults={"id"= null}, name="dashboard_list_form", methods={"POST", "GET"})
  45.      */
  46.     public function form(?string $id nullRequest $requestDashboardListRepository $dashboardListRepository)
  47.     {
  48.         if ($id) {
  49.             $dashboardList $dashboardListRepository->find($id);
  50.         } else {
  51.             $dashboardList = new DashboardList();
  52.         }
  53.         if (!$dashboardList) {
  54.             throw new NotFoundHttpException();
  55.         }
  56.         $form $this->createForm(DashboardListType::class, $dashboardList, ['action' => $this->generateUrl('dashboard_list_form', ['id' => $dashboardList->getId()])]);
  57.         $form->handleRequest($request);
  58.         if ($form->isSubmitted() && $form->isValid()) {
  59.             $dashboard $form->getData();
  60.             $dashboard->setCreatedAt(new \DateTime('now', new \DateTimeZone('Asia/Jakarta')));
  61.             $entityManager $this->getDoctrine()->getManager();
  62.             $entityManager->persist($dashboard);
  63.             $entityManager->flush();
  64.             $this->addFlash('notice''List dashboard berhasil disimpan');
  65.             return $this->redirectToRoute('dashboard_list');
  66.         }
  67.         return $this->render('/backend/dashboard_list/form.html.twig', ['form' => $form->createView()]);
  68.     }
  69.     /**
  70.      * @Route("/dashboard_list/{id}/delete_dashboard_list", name="dashboard_list_delete", methods={"GET"})
  71.      */
  72.     public function delete(?string $id nullDashboardListRepository $dashboardListRepository)
  73.     {
  74.         $dashboard_list $dashboardListRepository->find($id);
  75.         $entityManager $this->getDoctrine()->getManager();
  76.         $entityManager->remove($dashboard_list);
  77.         $entityManager->flush();
  78.         return $this->redirectToRoute('dashboard_list');
  79.     }
  80.     /**
  81.      * @Route("/add_selected", name="dashboard_list_add_selected", methods={"POST"})
  82.      */
  83.     public function add_selected(Request $requestObjectManager $objectManager)
  84.     {
  85.         $sessionName $request->get("name");
  86.         $this->get('session')->set($sessionName$request->get('selected'));
  87.         $selected = (!empty($this->get('session')->get($sessionName))) ? $this->get('session')->get($sessionName) : [];
  88.         return $this->json($selected);
  89.     }
  90.     /**
  91.      * @Route("/action_selected", name="dashboard_list_action_selected", methods={"POST"})
  92.      */
  93.     public function action_selected(Request $requestObjectManager $objectManager)
  94.     {
  95.         $sessionName $request->get("name");
  96.         if ($this->isCsrfTokenValid($sessionName '_action_selected'$request->request->get('_token'))) {
  97.             $selected = (!empty($this->get('session')->get($sessionName))) ? $this->get('session')->get($sessionName) : [];
  98.             $deleted $objectManager->deleteByIds($this->class$selected);
  99.             if ($deleted) {
  100.                 $this->get('session')->set($sessionName, []);
  101.                 $this->addFlash('success'$this->getTranslator()->trans('messages.deleted.success'));
  102.             } else {
  103.                 $this->addFlash('error'$this->getTranslator()->trans('messages.deleted.error'));
  104.             }
  105.         }
  106.         return $this->redirectToRoute('dashboard_list');
  107.     }
  108.     // /**
  109.     //  * @Route("/dashboard_list/{id}/preview", name="dashboard_list_preview", methods={"GET", "POST"})
  110.     //  */
  111.     // public function preview(BreacrumbBuilder $builder, DashboardListRepository $dashboardListRepository, DashboardList $dashboardList, DashboardComponentRepository $dashboardComponentRepository)
  112.     // {
  113.     //     $builder->add('Setting Dashboard ', "dashboard_list", array(), "&nbsp;<i class='fa fa-home'></i>");
  114.     //     $builder->add('Preview');
  115.     //     $dashboardList = $dashboardListRepository->find($dashboardList);
  116.     //     $tabs = $dashboardList->getDashboardTabs()->toArray();
  117.     //     usort($tabs, fn($a, $b) => $a->getUrutan() <=> $b->getUrutan());
  118.     //     $componentsByTab = [];
  119.     //     foreach ($tabs as $tab) {
  120.     //         $componentsByTab[$tab->getId()] = $dashboardComponentRepository->findBy(['dashboard_tab' => $tab]);
  121.     //     }
  122.     //     return $this->render('backend/dashboard_list/preview.html.twig', [
  123.     //         'page_name' => $this->pageName,
  124.     //         'button_credential' => $this->buttonCredentials($this->pageName),
  125.     //         'dashboardList' => $dashboardList,
  126.     //         'tabs' => $tabs,
  127.     //         'componentsByTab' => $componentsByTab
  128.     //     ]);
  129.     // }
  130.     /**
  131.      * @Route("/dashboard_list/{id}/preview", name="dashboard_list_preview", methods={"GET", "POST"})
  132.      */
  133.     public function preview(
  134.         BreacrumbBuilder $builder,
  135.         DashboardListRepository $dashboardListRepository,
  136.         DashboardList $dashboardList,
  137.         DashboardComponentRepository $dashboardComponentRepository,
  138.         TGrafikRepository $tGrafikRepo,
  139.         EntityManagerInterface $em
  140.     ) {
  141.         $builder->add('Setting Dashboard '"dashboard_list", [], "&nbsp;<i class='fa fa-home'></i>");
  142.         $builder->add('Preview');
  143.         $dashboardList $dashboardListRepository->find($dashboardList);
  144.         $tabs $dashboardList->getDashboardTabs()->toArray();
  145.         usort($tabs, fn($a$b) => $a->getUrutan() <=> $b->getUrutan());
  146.         $componentsByTab = [];
  147.         $components = [];
  148.         foreach ($tabs as $tab) {
  149.             $components $dashboardComponentRepository->findBy(['dashboard_tab' => $tab]);
  150.             foreach ($components as $component) {
  151.                 // if ($component->getType() === 'table') {
  152.                 //     $grafikId = $component->getExternalChartId();
  153.                 //     $tGrafik = $tGrafikRepo->find($grafikId);
  154.                 //     if ($tGrafik) {
  155.                 //         $columns = $this->getGrafikColumns($tGrafik);
  156.                 //         $component->setColumns($columns);
  157.                 //         $em->persist($component);
  158.                 //     }
  159.                 // }
  160.                 if ($component->getType() === 'table') {
  161.                     $config $component->getConfig();
  162.                     $dataSourceType $config['data_source_type'] ?? 't_grafik';
  163.                     if ($dataSourceType === 't_grafik') {
  164.                         $grafikId $component->getExternalChartId();
  165.                         $tGrafik $tGrafikRepo->find($grafikId);
  166.                         if ($tGrafik) {
  167.                             $columns $this->getGrafikColumns($tGrafik);
  168.                             $columns array_filter($columns, fn($c) => $c !== 'all');
  169.                             $component->setColumns($columns);
  170.                             $em->persist($component);
  171.                         }
  172.                     } elseif ($dataSourceType === 't_explore_data_detail') {
  173.                         // Sesuaikan kolom default eksplorasi
  174.                         $columns = ['no''periode''nilai'];
  175.                         $component->setColumns($columns);
  176.                         $em->persist($component);
  177.                     }
  178.                 }
  179.                 if ($component->getType() === 'html') {
  180.                     $grafikId $component->getDataSource();
  181.                     $tGrafik $tGrafikRepo->find($grafikId);
  182.                     if ($tGrafik) {
  183.                         $conn $em->getConnection();
  184.                         $table $tGrafik->getTabel();
  185.                         // map khusus 'kategori_plant' → 'plant'
  186.                         $axisX $tGrafik->getAxisx() === 'kategori_plant' 'plant' $tGrafik->getAxisx();
  187.                         $axisY $tGrafik->getAxisYIds(); // array nama kolom Y
  188.                         $operation $tGrafik->getOperation() ?: 'COUNT';
  189.                         // build SELECT
  190.                         $selectParts = [];
  191.                         foreach ($axisY as $col) {
  192.                             $selectParts[] = sprintf('%s("%s") AS "%s"'$operation$colstrtolower($col)); // alias ke lowercase
  193.                         }
  194.                         $selectClause sprintf('"%s", %s'$axisXimplode(', '$selectParts));
  195.                         $sql sprintf('SELECT %s FROM "%s" GROUP BY "%s" ORDER BY "%s" LIMIT 1'$selectClause$table$axisX$axisX);
  196.                         try {
  197.                             $stmt $conn->prepare($sql);
  198.                             $data $stmt->executeQuery()->fetchAllAssociative();
  199.                         } catch (\Throwable $e) {
  200.                             $data = [];
  201.                         }
  202.                         // normalisasi key ke lowercase, termasuk axisX
  203.                         $firstRow = [];
  204.                         if (!empty($data[0])) {
  205.                             foreach ($data[0] as $key => $val) {
  206.                                 $firstRow[strtolower($key)] = $val;
  207.                             }
  208.                             // pastikan axisX juga tersedia sebagai 'plant' bila relevan
  209.                             if ($axisX !== strtolower($axisX) && isset($data[0][$axisX])) {
  210.                                 $firstRow[strtolower($axisX)] = $data[0][$axisX];
  211.                             }
  212.                         }
  213.                         $template $component->getConfig()['html_template'] ?? '';
  214.                         // ↓ turunkan placeholder ke lowercase sebelum lookup
  215.                         $replacedHtml preg_replace_callback('/\{\{\s*([A-Za-z0-9_]+)\s*\}\}/', function ($m) use ($firstRow) {
  216.                             $key strtolower($m[1]);
  217.                             if (array_key_exists($key$firstRow)) {
  218.                                 // aman-kan value agar tidak injeksi; HTML murni dari template tetap dipertahankan
  219.                                 return htmlspecialchars((string) $firstRow[$key], ENT_QUOTES ENT_SUBSTITUTE'UTF-8');
  220.                             }
  221.                             return "<span style='color:red'>[undefined: {$m[1]}]</span>";
  222.                         }, $template);
  223.                         $component->setResolvedData([$replacedHtml]);
  224.                         $em->persist($component); // pastikan entity flagged as dirty
  225.                     }
  226.                 }
  227.             }
  228.             $componentsByTab[$tab->getId()] = $components;
  229.         }
  230.         $em->flush();
  231.         return $this->render('backend/dashboard_list/preview.html.twig', [
  232.             'page_name' => $this->pageName,
  233.             'button_credential' => $this->buttonCredentials($this->pageName),
  234.             'dashboardList' => $dashboardList,
  235.             'tabs' => $tabs,
  236.             'componentsByTab' => $componentsByTab,
  237.             'components' => $components
  238.         ]);
  239.     }
  240.     private function getGrafikColumns(TGrafik $grafik): array
  241.     {
  242.         $sumbu_x = ($grafik->getAxisx() === 'kategori_plant') ? 'plant' $grafik->getAxisx();
  243.         $sumbu_y $grafik->getAxisYIds();
  244.         return array_merge([$sumbu_x], $sumbu_y);
  245.     }
  246.     /**
  247.      * @Route("/dashboard_list/tab/add", name="tab_add", methods={"POST"})
  248.      */
  249.     public function addTab(Request $requestEntityManagerInterface $emDashboardListRepository $repo): JsonResponse
  250.     {
  251.         $id $request->request->get('dashboard_id');
  252.         $dashboard $repo->find($id);
  253.         if (!$dashboard) {
  254.             return new JsonResponse(['success' => false'message' => 'Dashboard tidak ditemukan'], 404);
  255.         }
  256.         $lastTab $dashboard->getDashboardTabs()->last();
  257.         $lastUrutan $lastTab $lastTab->getUrutan() : 0;
  258.         $tab = new DashboardTab();
  259.         $tab->setName($request->request->get('nama_tab'));
  260.         $tab->setDashboardList($dashboard);
  261.         $tab->setUrutan($lastUrutan 1);
  262.         $tab->setCreatedAt(new \DateTime('now', new \DateTimeZone('Asia/Jakarta')));
  263.         $em->persist($tab);
  264.         $em->flush();
  265.         return new JsonResponse(['success' => true'tab_id' => $tab->getId()]);
  266.     }
  267.     /**
  268.      * @Route("/dashboard_list/tab/rename/{id}", methods={"POST"})
  269.      */
  270.     public function rename($idRequest $requestEntityManagerInterface $emDashboardTab $dashboardTab)
  271.     {
  272.         $newName $request->request->get('nama_tab');
  273.         $dashboardTab->setName($newName);
  274.         $em->flush();
  275.         return new JsonResponse(['success' => true]);
  276.     }
  277.     /**
  278.      * @Route("/dashboard_list/tab/delete/{id}", name="tab_delete", methods={"DELETE"})
  279.      */
  280.     public function deleteTab(DashboardTab $dashboardTabEntityManagerInterface $em): JsonResponse
  281.     {
  282.         $em->remove($dashboardTab);
  283.         $em->flush();
  284.         return new JsonResponse(['success' => true]);
  285.     }
  286. }