src/Controller/Backend/TRawDataController.php line 60

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Backend;
  3. use App\Controller\Base\BaseController;
  4. use App\Entity\TFileGrafik;
  5. use App\Entity\TGrafik;
  6. use App\Form\TGrafikType;
  7. use App\Entity\TGrafikDinamis;
  8. use App\Entity\THeader;
  9. use App\Entity\TProgres;
  10. use App\Entity\TRawData;
  11. use App\Entity\TVariabelGrafik;
  12. use App\Entity\TWeeklyEploreReport;
  13. use App\Repository\MKategoriDetailRepository;
  14. use App\Repository\MKategoriRepository;
  15. use App\Repository\TDivRepository;
  16. use App\Repository\TGrafikDinamisRepository;
  17. use App\Repository\TGrafikRepository;
  18. use App\Repository\TLogRepository;
  19. use App\Repository\TVariabelGrafikRepository;
  20. use App\Repository\TFileGrafikRepository;
  21. use Doctrine\Persistence\ManagerRegistry;
  22. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  23. use Symfony\Component\HttpFoundation\Response;
  24. use Symfony\Component\HttpFoundation\JsonResponse;
  25. use Symfony\Component\Routing\Annotation\Route;
  26. use Kematjaya\Breadcrumb\Lib\Builder as BreacrumbBuilder;
  27. use Symfony\Component\HttpFoundation\Request;
  28. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  29. use Kematjaya\ImportBundle\Manager\ImportManagerInterface;
  30. use Kematjaya\ImportBundle\DataSource\RemoteDataSource;
  31. use App\Transformer\PublikasiTransformer;
  32. use App\Transformer\VariabelTransformer;
  33. use DateTime;
  34. use Sonata\SeoBundle\Seo\SeoPageInterface;
  35. use PhpOffice\PhpSpreadsheet\IOFactory;
  36. use Knp\Component\Pager\PaginatorInterface;
  37. use App\Filter\TGrafikDinamisFilterType;
  38. use App\Kernel;
  39. use App\Repository\TDataGrafikRepository;
  40. use App\Repository\THeaderRepository;
  41. use App\Repository\TPostingLaporanRepository;
  42. use App\Repository\TProgresRepository;
  43. use App\Repository\TRawDataRepository;
  44. use Symfony\Component\Process\Process;
  45. use Symfony\Component\Process\Exception\ProcessFailedException;
  46. use PhpOffice\PhpSpreadsheet\Reader\IReadFilter;
  47. use Symfony\Component\HttpFoundation\BinaryFileResponse;
  48. use Symfony\Component\HttpFoundation\File\Exception\FileException;
  49. use Symfony\Component\HttpFoundation\ResponseHeaderBag;
  50. class TRawDataController extends BaseController
  51. {
  52.     private $pageName 't_raw_data';
  53.     private $class TRawData::class;
  54.     /**
  55.      * @Route("/t/raw/data", name="t_raw_data")
  56.      */
  57.     public function index(SeoPageInterface $seoPageBreacrumbBuilder $builderRequest $requestPaginatorInterface $paginatorInterface): Response
  58.     {
  59.         $userRoles $this->getUser()->getRoles();
  60.         $seoPage->addTitlePrefix("Dataset");
  61.         $builder->add('Dashboard '"dashboard", array(), "&nbsp;<i class='fa fa-home'></i>");
  62.         $builder->add('Raw Data');
  63.         // $array = $this->getDataTableRawData(null, null, null, null);
  64.         // print_r($array); exit;
  65.         $filter TGrafikDinamisFilterType::class;
  66.         $form $this->get('form.factory')->create($filter$this->getFilters($filter));
  67.         $queryBuilder $this->getQueryBuilder($this->class);
  68.         // if ($userRoles[0] != 'ROLE_ADMINISTRATOR' && $userRoles[0] != 'ROLE_WALIDATA' && $userRoles[0] != 'ROLE_SUPER_USER'){
  69.         //     $queryBuilder = $queryBuilder->where('this.div = ' . $this->getUser()->getDiv()->getId());
  70.         // }
  71.         $queryBuilder $this->buildFilter($request$form$queryBuilder)->addOrderBy("this.id""DESC");
  72.         $this->setSessionLimit($request);
  73.         $maxPerPage $request->getSession()->get("limit") ? $request->getSession()->get("limit") : $this->getLimit();
  74.         $pagination $paginatorInterface->paginate($queryBuilder$request->query->getInt('page'1), $maxPerPage);
  75.         // $raw_data = $this->getDataTableRawData(null, null, null, null);
  76.         $header $this->getDataHeader();
  77.         if (isset($header[0]['head1'])) {
  78.             $head1 $header[0]['head1'];
  79.             $processedHeaders = [];
  80.             $keys array_keys($head1);
  81.             $total count($keys);
  82.             $i 0;
  83.             while ($i $total) {
  84.                 $key $keys[$i];
  85.                 $label $head1[$key];
  86.                 if ($label !== null) {
  87.                     $colspan 1;
  88.                     $j $i 1;
  89.                     while ($j $total && $head1[$keys[$j]] === null) {
  90.                         $colspan++;
  91.                         $j++;
  92.                     }
  93.                     $processedHeaders[] = [
  94.                         'label' => $label,
  95.                         'colspan' => $colspan,
  96.                     ];
  97.                     $i += $colspan;
  98.                 } else {
  99.                     $i++;
  100.                 }
  101.             }
  102.         } else {
  103.             $processedHeaders null;
  104.         }
  105.         // print_r($raw_data); exit;
  106.         return $this->render('backend/t_raw_data/index.html.twig', [
  107.             'page_name' => $this->pageName,
  108.             'header' => $header,
  109.             'headers_grouped' => $processedHeaders,
  110.             'button_credential' => $this->buttonCredentials(),
  111.             'filter' => $form->createView(),
  112.             'pagination' => $pagination,
  113.         ]);
  114.     }
  115.     /**
  116.      * @Route("/t/raw/data_table", name="t_raw_data_table")
  117.      */
  118.     public function raw_data_table(SeoPageInterface $seoPageBreacrumbBuilder $builderRequest $requestPaginatorInterface $paginatorInterface): Response
  119.     {
  120.         $userRoles $this->getUser()->getRoles();
  121.         $seoPage->addTitlePrefix("Dataset");
  122.         $builder->add('Dashboard '"dashboard", array(), "&nbsp;<i class='fa fa-home'></i>");
  123.         $builder->add('Raw Data');
  124.         $filter TGrafikDinamisFilterType::class;
  125.         $form $this->get('form.factory')->create($filter$this->getFilters($filter));
  126.         $queryBuilder $this->getQueryBuilder($this->class);
  127.         // if ($userRoles[0] != 'ROLE_ADMINISTRATOR' && $userRoles[0] != 'ROLE_WALIDATA' && $userRoles[0] != 'ROLE_SUPER_USER'){
  128.         //     $queryBuilder = $queryBuilder->where('this.div = ' . $this->getUser()->getDiv()->getId());
  129.         // }
  130.         $queryBuilder $this->buildFilter($request$form$queryBuilder)->addOrderBy("this.id""DESC");
  131.         $this->setSessionLimit($request);
  132.         $maxPerPage $request->getSession()->get("limit") ? $request->getSession()->get("limit") : $this->getLimit();
  133.         $pagination $paginatorInterface->paginate($queryBuilder$request->query->getInt('page'1), $maxPerPage);
  134.         $raw_data $this->getDataTableRawData(nullnullnullnull);
  135.         $head1 $raw_data[0]['head1'];
  136.         $processedHeaders = [];
  137.         $keys array_keys($head1);
  138.         $total count($keys);
  139.         $i 0;
  140.         while ($i $total) {
  141.             $key $keys[$i];
  142.             $label $head1[$key];
  143.             if ($label !== null) {
  144.                 $colspan 1;
  145.                 $j $i 1;
  146.                 while ($j $total && $head1[$keys[$j]] === null) {
  147.                     $colspan++;
  148.                     $j++;
  149.                 }
  150.                 $processedHeaders[] = [
  151.                     'label' => $label,
  152.                     'colspan' => $colspan,
  153.                 ];
  154.                 $i += $colspan;
  155.             } else {
  156.                 $i++;
  157.             }
  158.         }
  159.         // print_r($raw_data); exit;
  160.         return $this->render('backend/t_raw_data/raw_data_table.html.twig', [
  161.             'page_name' => $this->pageName,
  162.             'raw_data' => $raw_data,
  163.             'headers_grouped' => $processedHeaders,
  164.             'button_credential' => $this->buttonCredentials(),
  165.             'filter' => $form->createView(),
  166.             'pagination' => $pagination,
  167.         ]);
  168.     }
  169.     /**
  170.      * @Route("/t_raw_data/{id}/delete_t_raw_data", name="t_raw_data_delete", methods={"GET"})
  171.      */
  172.     public function delete(?string $id nullTGrafikDinamisRepository $tGrafikDinamisRepoTLogRepository $tLogRepo)
  173.     {
  174.         $publikasi $tGrafikDinamisRepo->find($id);
  175.         // dump($kategori); exit;
  176.         $entityManager $this->getDoctrine()->getManager();
  177.         $entityManager->remove($publikasi);
  178.         $entityManager->flush();
  179.         $tLogRepo->setLog($this->getDoctrine()->getManager(), null$publikasi->getDiv()->getId(), "Ubah Dataset " $publikasi->getJudul(), $this->getUser()->getName());
  180.         $this->addFlash('notice''Dataset "' $publikasi->getJudul() . '" berhasil dihapus');
  181.         return $this->redirectToRoute('publikasi');
  182.     }
  183.     /**
  184.      * @Route("/t_raw_data/form_file", name="t_raw_data_form_file", methods={"GET", "POST"})
  185.      */
  186.     // public function form_file(?string $id, Request $request, THeaderRepository $tHeaderRepo, TRawDataRepository $tRawDataRepo, TProgresRepository $tProgresRepo, ManagerRegistry $managerRegistry, Kernel $kernel)
  187.     // {
  188.     //     $em = $managerRegistry->getManager();
  189.     //     // $raw_data = $tRawDataRepo->find($id);
  190.     //     // if(!$raw_data){
  191.     //     //     throw new NotFoundHttpException();
  192.     //     // }
  193.     //     // if($file_id){
  194.     //     //     $file = $tFileGrafikRepo->find($file_id);
  195.     //     // } else {
  196.     //     //     $file = new TFileGrafik();
  197.     //     // }
  198.     //     // if(!$file){
  199.     //     //     throw new NotFoundHttpException();
  200.     //     // }
  201.     //     if ($request->isMethod('POST')) {
  202.     //         // $files = $tFileGrafikRepo->findBy(['grafik'=>$publikasi]);
  203.     //         // // $fileFound = $publikasi->getTFiles()->count();
  204.     //         // $fileFound = count($files);
  205.     //         // if (!$file_id) {
  206.     //         //     $periode_desk = "";
  207.     //         //     $periode_order = 0;
  208.     //         //     $file->setGrafik($publikasi);
  209.     //         //     $file->setDeskripsi($periode_desk);
  210.     //         //     // $file->setPeriodeAwal(\DateTime::createFromFormat('Y-m-d', $periode_awal));
  211.     //         //     // $file->setPeriodeAkhir(\DateTime::createFromFormat('Y-m-d', $periode_akhir));
  212.     //         //     $file->setPeriodeOrder($periode_order);
  213.     //         //     $file->setCreatedAt(new \DateTimeImmutable());
  214.     //         // } else {
  215.     //         //     $file->setUpdatedAt(new \DateTimeImmutable());
  216.     //         //     $datafile = $tDataGrafikRepo->findBy(['file'=>$file]);
  217.     //         //     // $tempFileData = $file->getTData();
  218.     //         //     $tempFileData = $datafile;
  219.     //         //     foreach ($tempFileData as $temp) {
  220.     //         //         $em->remove($temp);
  221.     //         //         $em->flush();
  222.     //         //     }
  223.     //         // }
  224.     //         $uploads_directory = $this->getParameter('uploads_directory');
  225.     //         $dataFile = $request->files->get('file');
  226.     //         $filename = md5(uniqid() . $dataFile->getClientOriginalName()) . '.' . $dataFile->guessExtension();
  227.     //         $dataFile->move(
  228.     //             $uploads_directory,
  229.     //             $filename
  230.     //         );
  231.     //         $spreadsheet = IOFactory::load($uploads_directory . '/' . $filename);
  232.     //         $sheetData = $spreadsheet->getActiveSheet()->toArray(null, true, true, true);
  233.     //         // $header1 = array_values($sheetData[1]);
  234.     //         // if (!$fileFound) {
  235.     //         // foreach ($header as $head) {
  236.     //         //     $var = new TVariabelGrafik();
  237.     //         //     $var->setGrafik($publikasi);
  238.     //         //     $var->setNama(str_replace(" ", "_", strtolower($head)));
  239.     //         //     $var->setIsTampil(true);
  240.     //         //     $var->setCreatedAt(new \DateTimeImmutable());
  241.     //         //     $em->persist($var);
  242.     //         //     $em->flush();
  243.     //         // }
  244.     //         // }
  245.     //         $header1 = $sheetData[1];
  246.     //         $header2 = $sheetData[2];
  247.     //         unset($sheetData[1]);
  248.     //         unset($sheetData[2]);
  249.     //         // print_r(strtolower(json_encode($header1)))."<br>";
  250.     //         // print_r(strtolower(json_encode($header2)));exit;
  251.     //         //cek header
  252.     //         $connection = $this->getDoctrine()->getConnection();
  253.     //         $sql = "SELECT * FROM t_header WHERE LOWER(head_1::text) = LOWER(:head_1) AND LOWER(head_2::text) = LOWER(:head_2)";
  254.     //         $stmt = $connection->prepare($sql);
  255.     //         $result = $stmt->executeQuery(['head_1' => strtolower(json_encode($header1)), 'head_2' => strtolower(json_encode($header2)),]);
  256.     //         $header = $result->fetchAssociative();
  257.     //         // print_r($header); exit;
  258.     //         if ($header) {
  259.     //             $header = $tHeaderRepo->find(['id' => $header['id']]);
  260.     //             $header->setHead1($header1);
  261.     //             $header->setHead2($header2);
  262.     //             $header->setUpdatedAt(new \DateTimeImmutable());
  263.     //         } else {
  264.     //             // unlink($filename);
  265.     //             // $this->addFlash('error', 'Header Tidak Sesuai');
  266.     //             // return $this->redirectToRoute('t_raw_data');
  267.     //             //belum dipake dlu karena pasti 1 header
  268.     //             $header = new THeader();
  269.     //             $header->setHead1($header1);
  270.     //             $header->setHead2($header2);
  271.     //             $header->setCreatedAt(new \DateTimeImmutable());
  272.     //         }
  273.     //         $header->setFile($filename);
  274.     //         $em->persist($header);
  275.     //         $em->flush();
  276.     //         // exit;
  277.     //         $isi = $sheetData;
  278.     //         // print_r(count($isi)); exit;
  279.     //         $batchSize = 50;
  280.     //         $firstBatch = array_slice($sheetData, 0, $batchSize);
  281.     //         $remainingBatch = array_slice($sheetData, $batchSize);
  282.     //         $no = 1;
  283.     //         // foreach ($isi as $key => $value) {
  284.     //         //     //cek raw_data
  285.     //         //     $connection = $this->getDoctrine()->getConnection();
  286.     //         //     $sql = "SELECT * FROM t_raw_data WHERE isi::text = :isi";
  287.     //         //     $stmt = $connection->prepare($sql);
  288.     //         //     $result = $stmt->executeQuery(['isi' => json_encode($value)]);
  289.     //         //     $raw_data = $result->fetchAssociative();
  290.     //         //     if ($raw_data) {
  291.     //         //         $raw_data = $tRawDataRepo->find(['id' => $raw_data['id']]);
  292.     //         //         $raw_data->setIsi($value);
  293.     //         //         $raw_data->setUpdatedAt(new \DateTimeImmutable());
  294.     //         //     } else {
  295.     //         //         $raw_data = new TRawData();
  296.     //         //         $raw_data->setHeaderId($header->getId());
  297.     //         //         $raw_data->setIsi($value);
  298.     //         //         $raw_data->setCreatedAt(new \DateTimeImmutable());
  299.     //         //     }
  300.     //         //     // $raw_data->setFile($filename);
  301.     //         //     $em->persist($raw_data);
  302.     //         //     $em->flush();
  303.     //         // }
  304.     //         $t_progres = new TProgres();
  305.     //         $t_progres->setCreatedAt(new \DateTimeImmutable());
  306.     //         $t_progres->setReffKode('RAW_DATA');
  307.     //         $t_progres->setFile($filename);
  308.     //         $t_progres->setJumlahData(count($isi));
  309.     //         $em->persist($t_progres);
  310.     //         $em->flush();
  311.     //         $data_masuk = 1;
  312.     //         foreach ($firstBatch as $value) {
  313.     //             //cek raw_data
  314.     //             $connection = $this->getDoctrine()->getConnection();
  315.     //             $sql = "SELECT * FROM t_raw_data WHERE isi::text = :isi";
  316.     //             $stmt = $connection->prepare($sql);
  317.     //             $result = $stmt->executeQuery(['isi' => json_encode($value)]);
  318.     //             $raw_data = $result->fetchAssociative();
  319.     //             if ($raw_data) {
  320.     //                 $raw_data = $tRawDataRepo->find(['id' => $raw_data['id']]);
  321.     //                 $raw_data->setIsi($value);
  322.     //                 $raw_data->setUpdatedAt(new \DateTimeImmutable());
  323.     //             } else {
  324.     //                 $raw_data = new TRawData();
  325.     //                 $raw_data->setHeaderId($header->getId());
  326.     //                 $raw_data->setIsi($value);
  327.     //                 $raw_data->setCreatedAt(new \DateTimeImmutable());
  328.     //             }
  329.     //             //progress upload
  330.     //             $t_progres = $tProgresRepo->findOneBy(['reff_kode' => 'RAW_DATA']);
  331.     //             $t_progres->setDataMasuk($data_masuk);
  332.     //             $em->persist($t_progres);
  333.     //             $em->flush();
  334.     //             $tahun_anggaran = $request->request->get('tahun_anggaran');
  335.     //             $raw_data->setTahunAnggaran($tahun_anggaran);
  336.     //             $em->persist($raw_data);
  337.     //             $em->flush();
  338.     //             $data_masuk +=1;
  339.     //         }
  340.     //         $tempPath = $uploads_directory . '/batch_pending.json';
  341.     //         file_put_contents($tempPath, json_encode([
  342.     //             'header_id' => $header->getId(),
  343.     //             'data' => $remainingBatch
  344.     //         ]));
  345.     //         $baseCmd = sprintf('%s/bin/console app:rawdata "%s" "%s"', $this->getParameter('kernel.project_dir'), $tempPath,$tahun_anggaran);
  346.     //         if (strncasecmp(PHP_OS, 'WIN', 3) === 0) {
  347.     //             $cmd = 'start /B php ' . $baseCmd;
  348.     //         } else {
  349.     //             $cmd = 'php7.4 ' . $baseCmd . ' > /dev/null 2>&1 &';
  350.     //         }
  351.     //         $process = Process::fromShellCommandline($cmd);
  352.     //         $process->disableOutput();
  353.     //         $process->start();
  354.     //         // if (!$process->isStarted()) {
  355.     //         //     $managerRegistry->getManager()->remove($entity);
  356.     //         //     $managerRegistry->getManager()->flush();
  357.     //         // }
  358.     //         // $vars = $tVariabelGrafikRepo->findBy(['grafik'=>$publikasi->getId()], ['id'=>'asc']);
  359.     //         // $lastData = $tDataGrafikRepo->findOneBy(['grafik'=>$publikasi->getId()], ['id'=>'desc']);
  360.     //         // $rowNum = 1;
  361.     //         // if ($lastData) {
  362.     //         //     $rowNum += $lastData->getRowId();
  363.     //         // }
  364.     //         // foreach ($sheetData as $value) {
  365.     //         //     $arrData = array_values($value);
  366.     //         //     $isEmpty = trim(implode('', $arrData));
  367.     //         //     if ($isEmpty != '') {
  368.     //         //         foreach ($arrData as $key => $val) {
  369.     //         //             $data = new TDataGrafik();
  370.     //         //             $data->setGrafik($publikasi);
  371.     //         //             $data->setVariabel($vars[$key]);
  372.     //         //             $data->setIsi($val);
  373.     //         //             $data->setFile($file);
  374.     //         //             $data->setRowId($rowNum);
  375.     //         //             $data->setCreatedAt(new \DateTimeImmutable());
  376.     //         //             $em->persist($data);
  377.     //         //             $em->flush();
  378.     //         //         }
  379.     //         //     }
  380.     //         //     $rowNum++;
  381.     //         // }
  382.     //         $this->addFlash('notice', 'Upload file berhasil');
  383.     //         return $this->redirectToRoute('t_raw_data');
  384.     //     }
  385.     //     return $this->render('/backend/t_raw_data/form_file.html.twig', [
  386.     //         // 't_raw_data' => $raw_data,
  387.     //         // 'file' => $file,
  388.     //         // 'bulan' => $this->getBulan(),
  389.     //         // 'periode' => $this->getArrayPeriode()
  390.     //     ]);
  391.     // }
  392.     public function form_file(?string $idRequest $requestTHeaderRepository $tHeaderRepoTRawDataRepository $tRawDataRepoTProgresRepository $tProgresRepoTPostingLaporanRepository $tPostingLaporanRepoManagerRegistry $managerRegistryKernel $kernel)
  393.     {
  394.         $em $managerRegistry->getManager();
  395.         // $raw_data = $tRawDataRepo->find($id);
  396.         // if(!$raw_data){
  397.         //     throw new NotFoundHttpException();
  398.         // }
  399.         // if($file_id){
  400.         //     $file = $tFileGrafikRepo->find($file_id);
  401.         // } else {
  402.         //     $file = new TFileGrafik();
  403.         // }
  404.         // if(!$file){
  405.         //     throw new NotFoundHttpException();
  406.         // }
  407.         if ($request->isMethod('POST')) {
  408.             $uploads_directory $this->getParameter('uploads_directory');
  409.             // $tahun_anggaran = $request->get('tahun_anggaran');
  410.             $periode_upload $request->get('periode_upload');
  411.             // print_r($tahun_anggaran); exit;
  412.             // Upload file1'
  413.             $dataFile $request->files->get('file');
  414.             // --- 1. Cek ekstensi ---
  415.             $allowedExtensions = ['xls''xlsx'];
  416.             $extension strtolower($dataFile->getClientOriginalExtension());
  417.             if (!in_array($extension$allowedExtensions)) {
  418.                 // throw new \Exception('File harus berupa Excel (.xls atau .xlsx).');
  419.                 $this->addFlash('error''Upload Gagal!, File harus berupa Excel (.xls atau .xlsx).');
  420.                 return $this->redirectToRoute('t_raw_data');
  421.             }
  422.             // --- 2. Cek MIME type ---
  423.             $allowedMimeTypes = [
  424.                 'application/vnd.ms-excel',
  425.                 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  426.                 'application/octet-stream' // beberapa browser kadang kirim ini
  427.             ];
  428.             $mimeType $dataFile->getMimeType();
  429.             if (!in_array($mimeType$allowedMimeTypes)) {
  430.                 // throw new \Exception('Tipe file tidak valid, bukan file Excel.');
  431.                 $this->addFlash('error''Upload Gagal!, Tipe file tidak valid, bukan file Excel.');
  432.                 return $this->redirectToRoute('t_raw_data');
  433.             }
  434.             // --- 3. Cek isi file (signature sederhana) ---
  435.            
  436.             // Buka beberapa byte pertama untuk pastikan tidak mengandung kode PHP
  437.            
  438.             $firstBytes file_get_contents($dataFile->getPathname(), falsenull02048);
  439.             $dangerousPatterns = [
  440.                 '/<\?php/i',              // PHP
  441.                 '/<script\b/i',           // JS/HTML
  442.                 '/#!\/usr\/bin\/(python|bash|sh|perl)/i'// shebang
  443.                 '/eval\s*\(/i',
  444.                 '/base64_decode/i',
  445.                 '/shell_exec/i',
  446.                 '/exec\s*\(/i',
  447.                 '/os\.system/i',
  448.                 '/import\s+[a-z0-9_]+/i',
  449.                 '/function\s+[a-z0-9_]+\s*\(/i'
  450.             ];
  451.             foreach ($dangerousPatterns as $p) {
  452.                 if (preg_match($p$firstBytes)) {
  453.                     // hapus tmp file untuk kebersihan, lalu tolak
  454.                     @unlink($dataFile->getPathname());
  455.                     $this->addFlash('error''Upload Gagal!, File berisi kode PHP dan ditolak.');
  456.                     return $this->redirectToRoute('t_raw_data');
  457.                 }
  458.             }
  459.             // --- 4. Simpan dengan nama aman ---
  460.             $safeFilename md5(uniqid() . $dataFile->getClientOriginalName());
  461.             $filename $safeFilename '.' $extension;
  462.             try {
  463.                 $dataFile->move($uploads_directory$filename);
  464.             } catch (FileException $e) {
  465.                 // throw new \Exception('Gagal menyimpan file: ' . $e->getMessage());
  466.                 $this->addFlash('error''Gagal menyimpan file: ' $e->getMessage());
  467.                 return $this->redirectToRoute('t_raw_data');
  468.             }
  469.             // $filename = md5(uniqid() . $dataFile->getClientOriginalName()) . '.' . $dataFile->guessExtension();
  470.             // $dataFile->move($uploads_directory, $filename);
  471.             // Upload file2 (monitoring)
  472.             // $dataFileMonitoringFull = $request->files->get('file_monitoring_full');
  473.             // $filename_monitoring_full = md5(uniqid() . $dataFileMonitoringFull->getClientOriginalName()) . '.' . $dataFileMonitoringFull->guessExtension();
  474.             // $dataFileMonitoringFull->move($uploads_directory, $filename_monitoring_full);
  475.             // Convert keduanya jadi array
  476.             // $spreadsheet1 = IOFactory::load($uploads_directory . '/' . $filename);
  477.             // $sheetData1 = $spreadsheet1->getActiveSheet()->toArray(null, true, true, true);
  478.             // $spreadsheet2 = IOFactory::load($uploads_directory . '/' . $filename_monitoring_full);
  479.             // $sheetData2 = $spreadsheet2->getActiveSheet()->toArray(null, true, true, true);
  480.             //cek header
  481.             $reader IOFactory::createReader('Xlsx'); // atau 'Xls'
  482.             // Anonymous class implement IReadFilter
  483.             $reader->setReadFilter(new class implements IReadFilter {
  484.                 public function readCell($column$row$worksheetName '')
  485.                 {
  486.                     // hanya ambil baris 1–2
  487.                     return $row <= 2;
  488.                 }
  489.             });
  490.             $spreadsheet $reader->load($uploads_directory '/' $filename);
  491.             $sheetData $spreadsheet->getActiveSheet()->toArray(nulltruetruetrue);
  492.             // print_r($data);
  493.             // exit;
  494.             $header1 $sheetData[1];
  495.             $header2 $sheetData[2];
  496.             unset($sheetData[1]);
  497.             unset($sheetData[2]);
  498.             //cek header
  499.             $connection $this->getDoctrine()->getConnection();
  500.             $sql "SELECT * FROM t_header WHERE LOWER(head_1::text) = LOWER(:head_1) AND LOWER(head_2::text) = LOWER(:head_2)";
  501.             $stmt $connection->prepare($sql);
  502.             $result $stmt->executeQuery(['head_1' => strtolower(json_encode($header1)), 'head_2' => strtolower(json_encode($header2)),]);
  503.             $header $result->fetchAssociative();
  504.             // print_r($header); exit;
  505.             if ($header) {
  506.                 $header $tHeaderRepo->find(['id' => $header['id']]);
  507.                 $header->setHead1($header1);
  508.                 $header->setHead2($header2);
  509.                 $header->setUpdatedAt(new \DateTimeImmutable());
  510.                 $header->setPeriodeUpload(new \DateTime($periode_upload));
  511.             } else {
  512.                 // unlink($filename);
  513.                 $this->addFlash('error''Header Tidak Sesuai');
  514.                 return $this->redirectToRoute('t_raw_data');
  515.                 //belum dipake dlu karena pasti 1 header
  516.                 // $header = new THeader();
  517.                 // $header->setHead1($header1);
  518.                 // $header->setHead2($header2);
  519.                 // $header->setCreatedAt(new \DateTimeImmutable());
  520.             }
  521.             $header->setFile($filename);
  522.             $em->persist($header);
  523.             $em->flush();
  524.             // print_r('aa'); exit;
  525.             //initializing
  526.             $t_progres = new TProgres();
  527.             $t_progres->setCreatedAt(new \DateTimeImmutable());
  528.             $t_progres->setReffKode('INISIALISASI_DATA');
  529.             $em->persist($t_progres);
  530.             $em->flush();
  531.             // Jalankan background job
  532.             $baseCmd sprintf(
  533.                 '%s/bin/console app:rawdata "%s" "%s"',
  534.                 $this->getParameter('kernel.project_dir'),
  535.                 $filename,
  536.                 $periode_upload
  537.             );
  538.             if (strncasecmp(PHP_OS'WIN'3) === 0) {
  539.                 $cmd 'start /B php ' $baseCmd;
  540.             } else {
  541.                 $cmd 'php7.4 ' $baseCmd ' > /dev/null 2>&1 &';
  542.             }
  543.             $process Process::fromShellCommandline($cmd);
  544.             $process->disableOutput();
  545.             $process->start();
  546.             // $baseCmd = sprintf(
  547.             //     '%s/bin/console app:rawdata "%s" "%s"',
  548.             //     $this->getParameter('kernel.project_dir'),
  549.             //     $filename,
  550.             //     $tahun_anggaran
  551.             // );
  552.             // $php = PHP_BINARY;
  553.             // if (strncasecmp(PHP_OS, 'WIN', 3) === 0) {
  554.             //     // Windows â†’ jalankan lewat cmd.exe
  555.             //     $cmd = 'cmd /c start /B ' . $php . ' ' . $baseCmd;
  556.             // } else {
  557.             //     // Linux/Unix â†’ async pakai &
  558.             //     $cmd = $php . ' ' . $baseCmd . ' > /dev/null 2>&1 &';
  559.             // }
  560.             // $process = Process::fromShellCommandline($cmd);
  561.             // $process->disableOutput();
  562.             // $process->start();
  563.             // $php = PHP_BINARY;
  564.             // $console = $this->getParameter('kernel.project_dir') . '/bin/console';
  565.             // // print_r($console); exit;
  566.             // try {
  567.             //     // --- Utama: Symfony Process (aman, cross-platform) ---
  568.             //     $process = new Process([
  569.             //         $php,
  570.             //         $console,
  571.             //         'app:rawdata',
  572.             //         $filename,
  573.             //         $tahun_anggaran
  574.             //     ]);
  575.             //     $process->setWorkingDirectory($this->getParameter('kernel.project_dir'));
  576.             //     $process->disableOutput();
  577.             //     $process->start();
  578.             //     print_r('aa'); exit;
  579.             // } catch (\Throwable $e) {
  580.             //     // --- Fallback: exec() (string command) ---
  581.             //     if (strncasecmp(PHP_OS, 'WIN', 3) === 0) {
  582.             //         print_r('bb'); exit;
  583.             //         // Windows background
  584.             //         $cmd = sprintf(
  585.             //             'start /B %s %s app:rawdata %s %s',
  586.             //             $php,
  587.             //             $console,
  588.             //             escapeshellarg($filename),
  589.             //             escapeshellarg($tahun_anggaran)
  590.             //         );
  591.             //     } else {
  592.             //         // Linux/Unix background
  593.             //         $cmd = sprintf(
  594.             //             '%s %s app:rawdata %s %s > /dev/null 2>&1 &',
  595.             //             $php,
  596.             //             $console,
  597.             //             escapeshellarg($filename),
  598.             //             escapeshellarg($tahun_anggaran)
  599.             //         );
  600.             //     }
  601.             //     exec($cmd);
  602.             // }
  603.             $this->addFlash('notice''Upload file berhasil');
  604.             return $this->redirectToRoute('t_raw_data');
  605.         }
  606.         $lastUpdate $tPostingLaporanRepo->findOneBy([], ['tanggal' => 'DESC']);
  607.         $lastUpdate = ($lastUpdate) ? $lastUpdate->getTanggal()->format("Y-m-d") : null;
  608.         return $this->render('/backend/t_raw_data/form_file.html.twig', [
  609.             // 't_raw_data' => $raw_data,
  610.             'lastUpdate' => $lastUpdate,
  611.             // 'bulan' => $this->getBulan(),
  612.             // 'periode' => $this->getArrayPeriode()
  613.         ]);
  614.     }
  615.     /**
  616.      * @Route("/t_raw_data/{id}/delete_t_raw_data_file", name="t_raw_data_delete_file", methods={"GET"})
  617.      */
  618.     public function delete_file(
  619.         ?string $id null,
  620.         TFileGrafikRepository $tFileGrafikRepo,
  621.         ManagerRegistry $managerRegistry,
  622.         TGrafikDinamisRepository $tGrafikDinamisRepo
  623.     ) {
  624.         $em $managerRegistry->getManager();
  625.         $file $tFileGrafikRepo->find($id);
  626.         $pubId $file->getGrafik()->getId();
  627.         // $countFiles = $file->getPub()->getTFiles()->count();
  628.         $files $tFileGrafikRepo->findBy(['grafik' => $pubId]);
  629.         $countFiles count($files);
  630.         if ($countFiles == 1) {
  631.             $grafik $file->getGrafik()->getTGrafik();
  632.             if ($grafik) {
  633.                 $em->remove($grafik);
  634.             }
  635.             foreach ($file->getPub()->getTVariabels() as $var) {
  636.                 $em->remove($var);
  637.             }
  638.         }
  639.         $em->remove($file);
  640.         $em->flush();
  641.         $this->addFlash('notice''File berhasil dihapus');
  642.         return $this->redirectToRoute('publikasi_detail', ['id' => $pubId]);
  643.     }
  644.     /**
  645.      * @Route("/t_raw_data/progres", name="t_raw_data_progres", methods={"POST"})
  646.      */
  647.     public function progress(TProgresRepository $tProgresRepo)
  648.     {
  649.         $progress $tProgresRepo->findOneBy(['reff_kode' => 'RAW_DATA']);
  650.         $current null;
  651.         $total null;
  652.         if ($progress) {
  653.             $current $progress->getDataMasuk();
  654.             $total $progress->getJumlahData();
  655.         }
  656.         return new JsonResponse([
  657.             'show' => $progress true false,
  658.             'current' => $current,
  659.             'total' => $total
  660.         ]);
  661.     }
  662.     /**
  663.      * @Route("/publikasi/verifAll", name="publikasi_verif_all", methods={"GET"})
  664.      */
  665.     public function verifall(TPublikasiRepository $tPublikasiRepoMStatusRepository $mStatusRepoManagerRegistry $managerRegistry)
  666.     {
  667.         $em $managerRegistry->getManager();
  668.         $user $this->getUser();
  669.         if ($user->getRoles()[0] == 'ROLE_OPERATOR') {
  670.             $tPublikasi $tPublikasiRepo->findBy(['status' => 13'div' => $user->getDiv()->getId()]);
  671.             foreach ($tPublikasi as $pub) {
  672.                 $pub->setStatus($mStatusRepo->find(1));
  673.                 $em->persist($pub);
  674.             }
  675.             $this->addFlash('notice''Dataset berhasil diajukan publik');
  676.         } else {
  677.             $tPublikasi $tPublikasiRepo->findBy(['status' => 1]);
  678.             foreach ($tPublikasi as $pub) {
  679.                 $pub->setStatus($mStatusRepo->find(3));
  680.                 $em->persist($pub);
  681.             }
  682.             $this->addFlash('notice''Dataset berhasil diverifikasi');
  683.         }
  684.         $em->flush();
  685.         return $this->redirectToRoute('publikasi');
  686.     }
  687.     /**
  688.      * @Route("/t_raw_data_table", name="t_raw_data_table", methods={"GET", "POST"})
  689.      */
  690.     public function dataset_table(?string $idRequest $request)
  691.     {
  692.         // Ambil data dari sumber
  693.         $array $this->getDataTableRawData(nullnullnullnull);
  694.         $items $array['isi'] ?? [];
  695.         // Ambil parameter datatables
  696.         $draw = (int) $request->get('draw'1);
  697.         $start = (int) $request->get('start'0);
  698.         $length = (int) $request->get('length'10);
  699.         // Ambil parameter pencarian per kolom
  700.         $columns $request->get("columns", []);
  701.         $columnSearch = [];
  702.         foreach ($columns as $col) {
  703.             $columnName $col["data"] ?? '';
  704.             $searchValue $col["search"]["value"] ?? '';
  705.             if ($columnName !== '') {
  706.                 $columnSearch[$columnName] = $searchValue;
  707.             }
  708.         }
  709.         // Filter data berdasarkan input pencarian
  710.         $filteredData array_filter($items, function ($row) use ($columnSearch) {
  711.             foreach ($columnSearch as $columnName => $search) {
  712.                 if ($search !== '') {
  713.                     if (!isset($row[$columnName]) || stripos($row[$columnName], $search) === false) {
  714.                         return false;
  715.                     }
  716.                 }
  717.             }
  718.             return true;
  719.         });
  720.         // Total & filtered
  721.         $recordsTotal count($items);
  722.         $recordsFiltered count($filteredData);
  723.         // Pagination
  724.         $pagedData array_slice($filteredData$start$length);
  725.         // Response JSON untuk DataTables
  726.         return new JsonResponse([
  727.             'draw' => $draw,
  728.             'recordsTotal' => $recordsTotal,
  729.             'recordsFiltered' => $recordsFiltered,
  730.             'data' => array_values($pagedData),
  731.         ]);
  732.     }
  733.     /**
  734.      * @Route("/t_raw_data/inisialisasi", name="t_raw_data_inisialisasi", methods={"POST"})
  735.      */
  736.     public function inisialisasi(TProgresRepository $tProgresRepo)
  737.     {
  738.         $progress $tProgresRepo->findOneBy(['reff_kode' => 'INISIALISASI_DATA']);
  739.         return new JsonResponse([
  740.             'show' => $progress true false
  741.         ]);
  742.     }
  743.     /**
  744.      * @Route("/t_raw_data/download_template", name="t_raw_data_download_template", methods={"GET", "POST"})
  745.      */
  746.     public function download_template()
  747.     {
  748.         $filePath $this->getParameter('kernel.project_dir') . '/public/template_upload.xlsx';
  749.         if (!file_exists($filePath)) {
  750.             throw $this->createNotFoundException('File tidak ditemukan.');
  751.         }
  752.         $response = new BinaryFileResponse($filePath);
  753.         $response->setContentDisposition(
  754.             ResponseHeaderBag::DISPOSITION_ATTACHMENT,
  755.             'template_upload.xlsx'
  756.         );
  757.         return $response;
  758.     }
  759. }