use App\Helpers\Database;
use App\Helpers\Security;
use App\Helpers\Auth;
use PDO;
// ========================================================
// 1. SAVE (Handles both Create & Update with Safe Uploads)
// ========================================================
public function save(): void
{
$this->validateCsrf();
$id = !empty($_POST['vendor_id']) ? (int)$_POST['vendor_id'] : null;
$businessName = trim($_POST['business_name'] ?? '');
$ownerName = trim($_POST['owner_name'] ?? '');
$category = trim($_POST['category'] ?? '');
$phone = trim($_POST['phone'] ?? '');
$city = trim($_POST['city'] ?? '');
$servicesList = trim($_POST['services_list'] ?? '');
$price = !empty($_POST['price_starts_at']) ? (float)$_POST['price_starts_at'] : 0.00;
$plan = trim($_POST['subscription_plan'] ?? 'free');
$expiresAt = !empty($_POST['subscription_expires_at']) ? $_POST['subscription_expires_at'] : null;
$isVerified = !empty($_POST['is_verified']) ? 1 : 0;
// Required fields validation
if (empty($businessName) || empty($phone) || empty($city)) {
header('Location: /admin/vendors?error=missing_fields');
exit;
}
// Secure Image Upload Handler
$imagePath = null;
if (isset($_FILES['image']) && $_FILES['image']['error'] === UPLOAD_ERR_OK) {
$allowedMimes = ['image/jpeg', 'image/png', 'image/webp'];
$fileTmp = $_FILES['image']['tmp_name'];
$fileSize = $_FILES['image']['size'];
if ($fileSize <= 3 * 1024 * 1024) { // Max 3MB
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $fileTmp);
finfo_close($finfo);
if (in_array($mime, $allowedMimes, true)) {
$extMap = ['image/jpeg' => 'jpg', 'image/png' => 'png', 'image/webp' => 'webp'];
$ext = $extMap[$mime];
// Check both public/uploads and root uploads
$baseDir = dirname(__DIR__, 2);
$uploadDir = is_dir($baseDir . '/public') ? $baseDir . '/public/uploads/vendors/' : $baseDir . '/uploads/vendors/';
// HOSTINGER SAFE PERMISSION: 0755 (Never use 0777 on Hostinger)
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0755, true);
}
$filename = 'vendor_' . time() . '_' . bin2hex(random_bytes(3)) . '.' . $ext;
if (move_uploaded_file($fileTmp, $uploadDir . $filename)) {
$imagePath = '/uploads/vendors/' . $filename;
}
}
}
}
try {
$db = Database::getConnection();
if (!empty($id)) {
// UPDATE VENDOR
if ($imagePath) {
// Delete old image from server storage
$old = $db->prepare("SELECT image FROM vendors WHERE id = ?");
$old->execute([$id]);
$oldImg = $old->fetchColumn();
if ($oldImg) {
$base = dirname(__DIR__, 2);
@unlink($base . '/public' . $oldImg);
@unlink($base . $oldImg);
}
$sql = "UPDATE vendors SET business_name=?, owner_name=?, category=?, phone=?, city=?, services_list=?, price_starts_at=?, subscription_plan=?, subscription_expires_at=?, is_verified=?, image=? WHERE id=?";
$params = [$businessName, $ownerName, $category, $phone, $city, $servicesList, $price, $plan, $expiresAt, $isVerified, $imagePath, $id];
} else {
$sql = "UPDATE vendors SET business_name=?, owner_name=?, category=?, phone=?, city=?, services_list=?, price_starts_at=?, subscription_plan=?, subscription_expires_at=?, is_verified=? WHERE id=?";
$params = [$businessName, $ownerName, $category, $phone, $city, $servicesList, $price, $plan, $expiresAt, $isVerified, $id];
}
$db->prepare($sql)->execute($params);
if (class_exists('\App\Helpers\Security') && class_exists('\App\Helpers\Auth')) {
Security::logAudit(Auth::id(), 'UPDATE_VENDOR', 'vendors', $id);
}
} else {
// INSERT NEW VENDOR
$sql = "INSERT INTO vendors (business_name, owner_name, category, phone, city, services_list, price_starts_at, subscription_plan, subscription_expires_at, is_verified, image, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())";
$db->prepare($sql)->execute([$businessName, $ownerName, $category, $phone, $city, $servicesList, $price, $plan, $expiresAt, $isVerified, $imagePath]);
$newId = (int)$db->lastInsertId();
if (class_exists('\App\Helpers\Security') && class_exists('\App\Helpers\Auth')) {
Security::logAudit(Auth::id(), 'CREATE_VENDOR', 'vendors', $newId);
}
}
// View-compatible redirect param
header('Location: /admin/vendors?success=saved');
exit;
} catch (\Throwable $e) {
error_log('[VENDOR_SAVE_ERROR] ' . $e->getMessage());
header('Location: /admin/vendors?error=db_error');
exit;
}
}
// ========================================================
// 2. DELETE (Removes Record & Associated Uploaded Photo)
// ========================================================
public function delete(): void
{
$this->validateCsrf();
$id = (int)($_POST['vendor_id'] ?? ($_GET['id'] ?? 0));
if ($id > 0) {
try {
$db = Database::getConnection();
// Unlink image file
$old = $db->prepare("SELECT image FROM vendors WHERE id = ?");
$old->execute([$id]);
$oldImg = $old->fetchColumn();
if ($oldImg) {
$base = dirname(__DIR__, 2);
@unlink($base . '/public' . $oldImg);
@unlink($base . $oldImg);
}
$db->prepare("DELETE FROM vendors WHERE id = ?")->execute([$id]);
if (class_exists('\App\Helpers\Security') && class_exists('\App\Helpers\Auth')) {
Security::logAudit(Auth::id(), 'DELETE_VENDOR', 'vendors', $id);
}
} catch (\Throwable $e) {
error_log('[VENDOR_DELETE_ERROR] ' . $e->getMessage());
}
}
header('Location: /admin/vendors?success=deleted');
exit;
}
// ========================================================
// 3. TOGGLE VERIFY (Instant Status Inversion)
// ========================================================
public function toggleVerify(): void
{
$this->validateCsrf();
$id = (int)($_POST['vendor_id'] ?? 0);
if ($id > 0) {
try {
$db = Database::getConnection();
$db->prepare("UPDATE vendors SET is_verified = 1 - is_verified WHERE id = ?")->execute([$id]);
if (class_exists('\App\Helpers\Security') && class_exists('\App\Helpers\Auth')) {
Security::logAudit(Auth::id(), 'TOGGLE_VENDOR_VERIFY', 'vendors', $id);
}
} catch (\Throwable $e) {
error_log('[VENDOR_TOGGLE_ERROR] ' . $e->getMessage());
}
}
header('Location: /admin/vendors?success=status_updated');
exit;
}
Warning: http_response_code(): Cannot set response code - headers already sent (output started at /home/u163000859/domains/dsa.midexa.in/public_html/app/Controllers/VendorController.php:1) in /home/u163000859/domains/dsa.midexa.in/public_html/app/Helpers/Router.php on line 121