project_directory/app/Http/Controllers/DashboardController.php

534 lines
23 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Models\AksesFile;
use App\Models\FileDirectory;
use App\Models\LogActivity;
use App\Models\MasterKategori;
use App\Models\MasterKlasifikasi;
use App\Models\SubUnitKerja;
use App\Models\UnitKerja;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use setasign\Fpdi\Fpdi;
use ZipArchive;
use function PHPUnit\Framework\isEmpty;
class DashboardController extends Controller
{
public function index(){
$katDok = MasterKategori::where('statusenabled', true)->select('master_kategori_directory_id', 'nama_kategori_directory')->get();
$klasifikasiDok = MasterKlasifikasi::where('statusenabled', true)->select('master_klasifikasi_directory_id', 'nama_klasifikasi_directory')->get();
$authMapping = auth()->user()?->dataUser?->mappingUnitKerjaPegawai[0];
$authUnitKerja = $authMapping->objectunitkerjapegawaifk;
$authSubUnitKerja = $authMapping->objectsubunitkerjapegawaifk;
$allAkses = AksesFile::where(['statusenabled' => true, 'pegawai_id' => auth()->user()?->dataUser->id])->first();
$payload = [
'title' => 'Dashboard',
'katDok' => $katDok,
'klasifikasiDok' => $klasifikasiDok,
'authUnitKerja' => $authUnitKerja,
'authSubUnitKerja' => $authSubUnitKerja,
'allAkses' => $allAkses ?? null
];
return view('dashboard.index', $payload);
}
public function dataUnitKerja(){
$user = auth()->user()?->dataUser;
$akses = AksesFile::where(['pegawai_id' => $user->id, 'statusenabled' => true])->first();
$kategori = request('kategori');
$filterUnit = request('unitKerja');
$subUnit = request('subUnit');
$klasifikasi = request('klasifikasi');
$keyword = request('keyword');
$subArray = $subUnit ? explode(',', $subUnit) : [];
$katArray = $kategori ? explode(',', $kategori) : [];
$klaArray = $klasifikasi ? explode(',', $klasifikasi) : [];
$katDok = MasterKategori::when($katArray, fn($q) => $q->whereIn('master_kategori_directory_id', $katArray))->where('statusenabled', true)->select('master_kategori_directory_id', 'nama_kategori_directory')->get();
if ($katArray && $filterUnit && $subArray && $klaArray) {
/* mode pencarian lengkap */
$unitKerja = UnitKerja::where('statusenabled', true)
->where('id', $filterUnit)
->with(['subUnitKerja' => fn($q) => $q->whereIn('id', $subArray)
->with(['fileDirectory' => fn($q) => $q
->where('id_unit_kerja', $filterUnit)
->when($subArray, fn($q) => $q->whereIn('id_sub_unit_kerja', $subArray))
->when($katArray, fn($q) => $q->whereIn('master_kategori_directory_id', $katArray))
->when($klaArray, fn($q) => $q->whereIn('master_klasifikasi_directory_id', $klaArray))
->when($keyword, fn($q) =>
$q->where(function($query) use ($keyword) {
$query->where('file', 'ilike', "%{$keyword}%")
->orWhere('pegawai_nama_entry', 'ilike', "%{$keyword}%");
})
)
])
])
->select('id', 'name')
->get();
} elseif ($akses?->all_akses) {
/* all akses */
$unitKerja = UnitKerja::where('statusenabled', true)->with([ // muat relasi
'subUnitKerja' => fn($q) => $q->with([ // sub-unit
'fileDirectory' => fn($f) => $f->when($keyword, fn($q) =>
$q->where('file', 'ilike', "%{$keyword}%")
->orWhere('pegawai_nama_entry', 'ilike', "%{$keyword}%")
)
])
])
->select('id', 'name')
->get();
} elseif ($akses?->unit_akses) {
/* akses per unit */
$unitKerja = UnitKerja::where(['statusenabled' => true, 'id' => $akses->unit_akses])
->with([ // muat relasi
'subUnitKerja' => fn($q) => $q->with([ // sub-unit
'fileDirectory' => fn($f) => $f->when($keyword, fn($q) =>
$q->where(function($query) use ($keyword) {
$query->where('file', 'ilike', "%{$keyword}%")
->orWhere('pegawai_nama_entry', 'ilike', "%{$keyword}%");
})
)
])
])
->select('id', 'name')
->get();
} else {
/* default : unit & sub milik sendiri */
$authUnit = $user?->mappingUnitKerjaPegawai[0]?->objectunitkerjapegawaifk;
$authSub = $user?->mappingUnitKerjaPegawai[0]?->objectsubunitkerjapegawaifk;
$unitKerja = UnitKerja::where('statusenabled', true)
->where('id', $authUnit)
->with([ // 1. sub-unit milik user
'subUnitKerja' => fn($q) => $q->where('id', $authSub)
->with([ // 2. file-directory + filter keyword
'fileDirectory' => fn($f) => $f->when($keyword, fn($q) =>
$q->where(function($query) use ($keyword) {
$query->where('file', 'ilike', "%{$keyword}%")
->orWhere('pegawai_nama_entry', 'ilike', "%{$keyword}%");
})
)
])
])
->select('id', 'name')
->get();
}
$data = [
'unitKerja' => $unitKerja ?? null,
'katDok' => $katDok ?? null
];
return response()->json([
'status' => true,
'data' => $data,
], 200);
}
public function store(){
DB::connection('dbDirectory')->beginTransaction();
try {
$datas = request()->input('data');
$result = [];
foreach($datas as $index => $value){
$files = request()->file("data.fileUpload$index");
if(!empty($files)){
foreach ($files['file'] as $file) {
list($id_unit_kerja, $nama_unit_kerja) = explode('/', $value['id_unit_kerja'],2);
list($id_sub_unit_kerja, $nama_sub_unit_kerja) = explode('/', $value['id_sub_unit_kerja'],2);
list($master_kategori_directory_id, $nama_kategori) = explode('/', $value['master_kategori_directory_id'],2);
list($klasifikasi, $nama_klasifikasi) = explode('/', $value['klasifikasi'],2);
$payload = [
'master_klasifikasi_directory_id' => $klasifikasi,
'id_unit_kerja' => $id_unit_kerja,
'id_sub_unit_kerja' => $id_sub_unit_kerja,
'master_kategori_directory_id' => $master_kategori_directory_id,
'pegawai_id_entry' => auth()->user()->dataUser->id ?? 1,
'pegawai_nama_entry' => auth()->user()->dataUser->namalengkap ?? 'tes',
];
if($file){
$imageName = $file->getClientOriginalName();
$path = "{$nama_unit_kerja}/{$nama_sub_unit_kerja}/{$nama_kategori}/{$nama_klasifikasi}";
$file->storeAs($path, $imageName, 'file_directory');
$payload['file'] =$path .'/' .$imageName;
}
FileDirectory::create($payload);
}
}
}
DB::connection('dbDirectory')->commit();
return response()->json([
'status' => true,
'message' => 'Data berhasil disimpan',
'data' => count($result) == 1 ? $result[0] : $result
], 200);
} catch (\Throwable $th) {
DB::connection('dbDirectory')->rollBack();
return response()->json([
'status' => false,
'message' => $th->getMessage()
], 500);
}
}
public function OptionUnitKerja(){
$q = request()->get('q');
$query = UnitKerja::where('statusenabled', true);
$data = $query->when($q, function ($query, $q){
$query->where('name', 'ILIKE', '%' .$q . '%');
})
->select('id', 'name')->get();
return response()->json([
'status' => true,
'data' => $data
], 200);
}
public function deleteFile(string $id){
DB::connection('dbDirectory')->beginTransaction();
try {
$data = FileDirectory::where('file_directory_id', $id)->first();
if(!$data){
return response()->json([
'success' => false,
'message' => 'File tidak ditemukan'
]);
}
$oldPath= public_path('file/' . $data->file);
$fileInfo = pathinfo($data->file);
$newFileName = $fileInfo['filename'] . '_deleted.' . $fileInfo['extension'];
$newPath = public_path('file/' . $fileInfo['dirname'] . '/' . $newFileName);
if (file_exists($oldPath)) {
// pastikan folder tujuan ada
if (!is_dir(dirname($newPath))) {
mkdir(dirname($newPath), 0777, true);
}
rename($oldPath, $newPath);
}
$data->update(['statusenabled' => false, 'file' => $fileInfo['dirname'].'/'. $newFileName]);
$payloadLog = [
'file_directory_id' => $data->file_directory_id,
'pegawai_id_entry' => $data->pegawai_id_entry,
'pegawai_nama_entry' => $data->pegawai_nama_entry,
'entry_at' => $data->entry_at,
'action_type' => 'Hapus Dokumen',
'statusenabled' => true,
'mod_change' => $data->entry_at,
'id_unit_kerja' => $data->id_unit_kerja,
'id_sub_unit_kerja' => $data->id_sub_unit_kerja,
'file' => $data->file,
'tanggal_terbit' => $data->tanggal_terbit,
'no_dokumen' => $data->no_dokumen,
'permission_file' => $data->permission_file,
];
LogActivity::create($payloadLog);
DB::connection('dbDirectory')->commit();
return response()->json([
'success' => true,
'message' => 'Berhasil menghapus data'
]);
} catch (\Throwable $th) {
DB::connection('dbDirectory')->rollBack();
return response()->json([
'success' => false,
'message' => 'Gagal menghapus data'
]);
//throw $th;
}
}
public function optionSubUnitKerja(string $id){
$data = SubUnitKerja::where('statusenabled', true)->where('objectunitkerjapegawaifk', $id)->get();
return response()->json([
'status' => true,
'data' => $data,
]);
}
public function getFile($id_unit_kerja, $id_sub_unit_kerja, $master_kategori_directory_id){
$klasifikasi = request('klasifikasi');
$klaArray = explode(',', $klasifikasi);
$data = FileDirectory::where(['statusenabled' => true, 'id_unit_kerja' => $id_unit_kerja, 'id_sub_unit_kerja' => $id_sub_unit_kerja, 'master_kategori_directory_id' => $master_kategori_directory_id])->whereIn('master_klasifikasi_directory_id', $klaArray)->get();
return response()->json([
'data' => $data,
'status' => true,
]);
}
public function downloadDataMultiple(){
try {
$rows = request('ids', []); // [[unit_id=>u, sub_unit_id=>s], ...]
if (empty($rows)) {
return response()->json(['message' => 'Tidak ada data'], 422);
}
$paths = [];
foreach ($rows as $r) {
if(!empty($r['sub_unit_id'])){
$files = FileDirectory::where('id_sub_unit_kerja', $r['sub_unit_id'])->where('statusenabled', true)->pluck('file');
$paths = array_merge($paths, $files->toArray());
}
}
$paths = array_unique($paths);
if (empty($paths)) {
return response()->json(['message' => 'File tidak ditemukan'], 404);
}
$zipName = 'files_' . time() . '.zip';
$zipPath = public_path('zip/' . $zipName);
$zip = new ZipArchive;
if($zip->open($zipPath, ZipArchive::CREATE) === TRUE){
foreach ($paths as $path) {
$fullPath = public_path('file/' . $path);
if(file_exists($fullPath)){
$relativePathInZip = $path;
$zip->addFile($fullPath, $relativePathInZip);
}else{
throw new \Exception("File tidak ditemukan: " . $path);
}
}
$zip->close();
}
return response()->download(public_path('zip/' . $zipName))->deleteFileAfterSend(true);
//code...
} catch (\Throwable $th) {
return response()->json([
'message' => 'Terjadi kesalahan',
'error' => $th->getMessage()
], 500);
}
}
public function downloadDataFolder(){
try {
$id = request('id');
$type = request('type');
if($type === "unit"){
$data = FileDirectory::where('id_unit_kerja', $id)->where('statusenabled', true)->pluck('file');
}else{
$data = FileDirectory::where('id_sub_unit_kerja', $id)->where('statusenabled', true)->pluck('file');
}
if (empty($data)) {
return response()->json(['message' => 'File tidak ditemukan'], 404);
}
$zipName = 'files_' . time() . '.zip';
$zipPath = public_path('zip/' . $zipName);
$zip = new ZipArchive;
if($zip->open($zipPath, ZipArchive::CREATE) === TRUE){
foreach ($data as $path) {
$fullPath = public_path('file/' . $path);
if(file_exists($fullPath)){
$relativePathInZip = $path;
$zip->addFile($fullPath, $relativePathInZip);
}else{
throw new \Exception("File tidak ditemukan: " . $path);
}
}
$zip->close();
}
return response()->download(public_path('zip/' . $zipName))->deleteFileAfterSend(true);
} catch (\Throwable $th) {
return response()->json([
'message' => 'Terjadi kesalahan',
'error' => $th->getMessage()
], 500);
}
}
public function dashboardVersion2(){
$katDok = MasterKategori::where('statusenabled', true)->select('master_kategori_directory_id', 'nama_kategori_directory')->get();
$authMapping = auth()->user()?->dataUser?->mappingUnitKerjaPegawai[0];
$authUnitKerja = $authMapping->objectunitkerjapegawaifk;
$authSubUnitKerja = $authMapping->objectsubunitkerjapegawaifk;
$data = [
'title' => 'Dashboard',
'katDok' => $katDok,
'authUnitKerja' => $authUnitKerja,
'authSubUnitKerja' => $authSubUnitKerja,
];
return view('dashboardV2.index', $data);
}
public function dataDocumentLast(){
$perPage = request('per_page', 10);
$data = FileDirectory::where('statusenabled', true)
->orderBy('entry_at', 'desc')
->paginate($perPage);
$payload = [
'status' => true,
'message' => 'Berhasil mendapatkan data',
'data' => $data->items(),
'pagination' => [
'current_page' => $data->currentPage(),
'next_page' => $data->hasMorePages() ? $data->currentPage() + 1 : null,
'has_more' => $data->hasMorePages()
]
];
return response()->json($payload);
}
public function storeVersion2(){
DB::connection('dbDirectory')->beginTransaction();
try {
$datas = request('data');
foreach ($datas as $data) {
list($id_unit_kerja, $nama_unit_kerja) = explode('/', $data['id_unit_kerja'],2);
list($id_sub_unit_kerja, $nama_sub_unit_kerja) = explode('/', $data['id_sub_unit_kerja'],2);
list($master_kategori_directory_id, $nama_kategori) = explode('/', $data['master_kategori_directory_id'],2);
$payload = [
'id_unit_kerja' => $id_unit_kerja,
'id_sub_unit_kerja' => $id_sub_unit_kerja,
'master_kategori_directory_id' => $master_kategori_directory_id,
'pegawai_id_entry' => auth()->user()->dataUser->id ?? 1,
'pegawai_nama_entry' => auth()->user()->dataUser->namalengkap ?? null,
'tanggal_terbit' => $data['date_active'] ?? null,
'no_dokumen' => $data['no_dokumen'] ?? null,
'permission_file' => $data['is_permission'] === "1" ? true : false,
];
if(!empty($data['file'])){
$file = $data['file'];
$imageName = $file->getClientOriginalName();
$path = "{$nama_unit_kerja}/{$nama_sub_unit_kerja}/{$nama_kategori}";
$file->storeAs($path, $imageName, 'file_directory');
$payload['file'] =$path .'/' .$imageName;
}
$fd = FileDirectory::create($payload);
$payloadLog = [
'file_directory_id' => $fd->file_directory_id,
'pegawai_id_entry' => $fd->pegawai_id_entry,
'pegawai_nama_entry' => $fd->pegawai_nama_entry,
'entry_at' => $fd->entry_at,
'action_type' => 'Upload Dokumen',
'statusenabled' => true,
'mod_change' => $fd->entry_at,
'id_unit_kerja' => $fd->id_unit_kerja,
'id_sub_unit_kerja' => $fd->id_sub_unit_kerja,
'file' => $fd->file,
'tanggal_terbit' => $fd->tanggal_terbit,
'no_dokumen' => $fd->no_dokumen,
'permission_file' => $fd->permission_file,
];
LogActivity::create($payloadLog);
}
DB::connection('dbDirectory')->commit();
return response()->json([
'status' => true,
'message' => 'Data berhasil disimpan'
], 200);
} catch (\Throwable $th) {
DB::connection('dbDirectory')->rollback();
return response()->json([
'status' => false,
'message' => $th->getMessage()
], 500);
}
}
public function dataPdf($fileDirectoryId)
{
$data = FileDirectory::where('file_directory_id', $fileDirectoryId)->first();
$filePath = public_path('file/' . $data->file);
if (!file_exists($filePath)) {
abort(404, 'PDF Tidak ditemukan');
}
$stampFile = public_path('assets/copy.png');
if (!file_exists($stampFile)) {
// kalau watermark tidak ada, tampilkan file asli
return response()->file($filePath, [
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'inline; filename="preview.pdf"',
'Cache-Control' => 'no-store, no-cache, must-revalidate, max-age=0',
]);
}
$tempConverted = storage_path('app/temp/' . uniqid('conv_') . '.pdf');
try {
// coba watermark langsung
return $this->watermarkCenterAndStream($filePath, $stampFile);
} catch (\Throwable $e) {
// kalau gagal (PDF modern) -> convert dulu
// dd($e);
$this->convertWithGhostscript($filePath, $tempConverted);
$resp = $this->watermarkCenterAndStream($tempConverted, $stampFile);
@unlink($tempConverted);
return $resp;
}
}
private function watermarkCenterAndStream(string $pdfPath, string $stampFile)
{
$pdf = new Fpdi();
$pageCount = $pdf->setSourceFile($pdfPath);
for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++) {
$tplId = $pdf->importPage($pageNo);
$size = $pdf->getTemplateSize($tplId);
$pdf->AddPage($size['orientation'], [$size['width'], $size['height']]);
$pdf->useTemplate($tplId);
// watermark tengah (skala adaptif)
$stampW = $size['width'] * 0.60;
$stampH = $stampW * 0.75; // sesuaikan rasio gambar kalau perlu
$x = ($size['width'] - $stampW) / 2;
$y = ($size['height'] - $stampH) / 2;
$pdf->Image($stampFile, $x, $y, $stampW, $stampH);
}
$output = $pdf->Output('S');
return response($output, 200, [
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'inline; filename="preview.pdf"',
'Cache-Control' => 'no-store, no-cache, must-revalidate, max-age=0',
]);
}
private function convertWithGhostscript(string $inputPdf, string $outputPdf): void
{
$gs = config('services.ghostscript.path');
if (!$gs || !file_exists($gs)) {
throw new \RuntimeException('Ghostscript tidak ditemukan. Cek GHOSTSCRIPT_PATH di .env');
}
$cmd = "\"{$gs}\" -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/prepress "
. "-dNOPAUSE -dBATCH -dQUIET -sOutputFile=\"{$outputPdf}\" \"{$inputPdf}\"";
exec($cmd, $out, $code);
if ($code !== 0 || !file_exists($outputPdf)) {
throw new \RuntimeException('Convert Ghostscript gagal (code=' . $code . ')');
}
}
}