2026-02-08 15:16:35 +07:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
|
|
|
|
|
|
use App\Models\Setting;
|
|
|
|
|
use App\Models\ActivityLog;
|
|
|
|
|
use App\Traits\LogsActivity;
|
|
|
|
|
use Illuminate\Http\Request;
|
|
|
|
|
use Illuminate\Support\Facades\Mail;
|
|
|
|
|
use Illuminate\Support\Facades\Http;
|
|
|
|
|
use Illuminate\Support\Facades\Storage;
|
2026-09-23 12:45:02 +07:00
|
|
|
use Illuminate\Support\Facades\Gate;
|
2026-02-08 15:16:35 +07:00
|
|
|
use Intervention\Image\Laravel\Facades\Image;
|
|
|
|
|
|
|
|
|
|
class SettingController extends Controller
|
|
|
|
|
{
|
|
|
|
|
use LogsActivity;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Daftar kunci pengaturan yang diizinkan untuk di-update secara massal.
|
|
|
|
|
*/
|
|
|
|
|
protected $allowedSettings = [
|
|
|
|
|
'app_name',
|
|
|
|
|
'app_slogan',
|
|
|
|
|
'app_version', // Tambahan baru
|
|
|
|
|
'app_address',
|
|
|
|
|
'wa_number'
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
public function index()
|
|
|
|
|
{
|
2026-09-23 12:45:02 +07:00
|
|
|
Gate::authorize('check-access', ['settings', 'read']);
|
2026-02-08 15:16:35 +07:00
|
|
|
$settings = Setting::pluck('value', 'key')->all();
|
|
|
|
|
|
|
|
|
|
// Tambahkan default jika version belum ada
|
|
|
|
|
if (!isset($settings['app_version'])) {
|
|
|
|
|
$settings['app_version'] = '1.0.0';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$waStatus = $this->checkWhatsAppService();
|
|
|
|
|
$emailStatus = $this->checkEmailService();
|
|
|
|
|
|
|
|
|
|
$logs = ActivityLog::with('user')
|
|
|
|
|
->where('action', 'LIKE', '%SETTING%')
|
|
|
|
|
->latest()
|
|
|
|
|
->take(5)
|
|
|
|
|
->get();
|
|
|
|
|
|
|
|
|
|
return view('pages.admin.settings', compact('settings', 'waStatus', 'emailStatus', 'logs'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function update(Request $request)
|
|
|
|
|
{
|
2026-09-23 12:45:02 +07:00
|
|
|
Gate::authorize('check-access', ['settings', 'update']);
|
2026-02-08 15:16:35 +07:00
|
|
|
$request->validate([
|
|
|
|
|
'app_logo' => 'nullable|image|mimes:png,jpg,jpeg|max:2048',
|
|
|
|
|
'app_favicon' => 'nullable|image|mimes:png,jpg,ico|max:512',
|
|
|
|
|
'app_name' => 'required|string|max:100',
|
|
|
|
|
'app_slogan' => 'nullable|string|max:255',
|
|
|
|
|
'app_version' => 'required|string|max:20', // Validasi versi
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
// 1. Proses Logo & Favicon
|
|
|
|
|
if ($request->hasFile('app_logo')) {
|
|
|
|
|
$this->uploadAndProcessImage($request->file('app_logo'), 'app_logo', 512);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($request->hasFile('app_favicon')) {
|
|
|
|
|
$this->uploadAndProcessImage($request->file('app_favicon'), 'app_favicon', 128);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 2. Update Pengaturan Teks (Hanya yang ada di whitelist)
|
|
|
|
|
foreach ($this->allowedSettings as $key) {
|
|
|
|
|
if ($request->has($key)) {
|
|
|
|
|
Setting::updateOrCreate(['key' => $key], ['value' => $request->get($key)]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->logAction('UPDATED_SETTINGS', null, "Memperbarui identitas sistem ke versi " . $request->app_version);
|
|
|
|
|
|
|
|
|
|
return back()->with('success', 'Konfigurasi ' . $request->app_name . ' berhasil diperbarui!');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Helper Image Processing (Intervention Image v3)
|
|
|
|
|
*/
|
|
|
|
|
private function uploadAndProcessImage($file, $key, $size)
|
|
|
|
|
{
|
|
|
|
|
$oldFile = Setting::where('key', $key)->value('value');
|
|
|
|
|
if ($oldFile && Storage::disk('public')->exists($oldFile)) {
|
|
|
|
|
Storage::disk('public')->delete($oldFile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$filename = $key . '_' . time() . '.png';
|
|
|
|
|
$path = 'settings/' . $filename;
|
|
|
|
|
|
|
|
|
|
// Intervention Image v3 Logic
|
|
|
|
|
$image = Image::read($file);
|
|
|
|
|
$image->cover($size, $size);
|
|
|
|
|
|
|
|
|
|
Storage::disk('public')->put($path, (string) $image->toPng());
|
|
|
|
|
Setting::updateOrCreate(['key' => $key], ['value' => $path]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function checkWhatsAppService()
|
|
|
|
|
{
|
|
|
|
|
// Gunakan cache atau timeout pendek agar page load tidak berat
|
|
|
|
|
try {
|
|
|
|
|
$response = Http::timeout(3)->withHeaders([
|
|
|
|
|
'Authorization' => config('services.fonnte.token') ?? env('FONNTE_TOKEN'),
|
|
|
|
|
])->post('https://api.fonnte.com/device');
|
|
|
|
|
|
|
|
|
|
$data = $response->json();
|
|
|
|
|
return [
|
|
|
|
|
'active' => ($data['status'] ?? false) == true,
|
|
|
|
|
'quota' => $data['quota'] ?? 0,
|
|
|
|
|
'message' => ($data['status'] ?? false) ? 'API Terhubung' : ($data['reason'] ?? 'Perangkat tidak aktif')
|
|
|
|
|
];
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
return ['active' => false, 'quota' => 0, 'message' => 'Layanan WA Offline'];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function checkEmailService()
|
|
|
|
|
{
|
|
|
|
|
try {
|
|
|
|
|
$transport = Mail::getSymfonyTransport();
|
|
|
|
|
|
|
|
|
|
// 1. Cek jika menggunakan driver 'log' (biasanya di localhost)
|
|
|
|
|
if ($transport instanceof \Illuminate\Mail\Transport\LogTransport) {
|
|
|
|
|
return [
|
|
|
|
|
'active' => true,
|
|
|
|
|
'message' => 'Mail Mode: LOG (Local Development)'
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 2. Jika menggunakan SMTP, coba lakukan jabat tangan (handshake)
|
|
|
|
|
if (method_exists($transport, 'start')) {
|
|
|
|
|
$transport->stop();
|
|
|
|
|
$transport->start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ['active' => true, 'message' => 'SMTP Terhubung'];
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
// Jika gagal konek ke Mailtrap/Gmail, kembalikan status false
|
|
|
|
|
return [
|
|
|
|
|
'active' => false,
|
|
|
|
|
'message' => 'SMTP Error: ' . $e->getMessage()
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|