use App\Helpers\Database; use App\Helpers\Security; use App\Helpers\Auth; use PDO; // ======================================================== // 1. SAVE (Creates & Updates with Full Schema & Image Upload) // ======================================================== public function save(): void { $this->validateCsrf(); $id = !empty($_POST['vendor_id']) ? (int)$_POST['vendor_id'] : (!empty($_POST['id']) ? (int)$_POST['id'] : null); $businessName = trim($_POST['business_name'] ?? ''); $ownerName = trim($_POST['owner_name'] ?? ''); $category = trim($_POST['category'] ?? ''); $phone = trim($_POST['phone'] ?? ''); $email = trim($_POST['email'] ?? ''); $city = trim($_POST['city'] ?? ''); $address = trim($_POST['address'] ?? ''); $servicesList = trim($_POST['services_list'] ?? ''); $price = !empty($_POST['price_starts_at']) ? max(0, (float)$_POST['price_starts_at']) : 0.00; $isVerified = !empty($_POST['is_verified']) ? 1 : 0; $status = in_array($_POST['status'] ?? 'active', ['active', 'inactive', 'suspended'], true) ? $_POST['status'] : 'active'; // Whitelist Subscription Plan $allowedPlans = ['free', 'silver', 'gold', 'platinum']; $plan = in_array(strtolower(trim($_POST['subscription_plan'] ?? 'free')), $allowedPlans, true) ? strtolower(trim($_POST['subscription_plan'])) : 'free'; // Safe Expiry Date check (Valid Y-m-d or NULL) $rawDate = trim($_POST['subscription_expires_at'] ?? ''); $expiresAt = (!empty($rawDate) && strtotime($rawDate) !== false) ? date('Y-m-d', strtotime($rawDate)) : null; // Mandatory fields check if (empty($businessName) || empty($phone) || empty($city)) { header('Location: /admin/vendors?error=missing_fields'); exit; } // Email format validation (agar provided ho) if (!empty($email) && !filter_var($email, FILTER_VALIDATE_EMAIL)) { $email = null; } // Secure File 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) { // 3MB limit $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]; $baseDir = dirname(__DIR__, 2); $uploadDir = is_dir($baseDir . '/public') ? $baseDir . '/public/uploads/vendors/' : $baseDir . '/uploads/vendors/'; // Hostinger Safe Directory Permission (0755) 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 EXISTING VENDOR ================= if ($imagePath) { // Purani image ko fetch karke naye image se replace karein $old = $db->prepare("SELECT image FROM vendors WHERE id = ?"); $old->execute([$id]); $oldImg = $old->fetchColumn(); if ($oldImg) { $this->deleteVendorImage($oldImg); } $sql = "UPDATE vendors SET business_name = ?, owner_name = ?, category = ?, phone = ?, email = ?, city = ?, address = ?, services_list = ?, price_starts_at = ?, subscription_plan = ?, subscription_expires_at = ?, is_verified = ?, status = ?, image = ? WHERE id = ?"; $params = [$businessName, $ownerName, $category, $phone, $email, $city, $address, $servicesList, $price, $plan, $expiresAt, $isVerified, $status, $imagePath, $id]; } else { $sql = "UPDATE vendors SET business_name = ?, owner_name = ?, category = ?, phone = ?, email = ?, city = ?, address = ?, services_list = ?, price_starts_at = ?, subscription_plan = ?, subscription_expires_at = ?, is_verified = ?, status = ? WHERE id = ?"; $params = [$businessName, $ownerName, $category, $phone, $email, $city, $address, $servicesList, $price, $plan, $expiresAt, $isVerified, $status, $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, email, city, address, services_list, price_starts_at, subscription_plan, subscription_expires_at, is_verified, status, image, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())"; $db->prepare($sql)->execute([$businessName, $ownerName, $category, $phone, $email, $city, $address, $servicesList, $price, $plan, $expiresAt, $isVerified, $status, $imagePath]); $newId = (int)$db->lastInsertId(); if (class_exists('\App\Helpers\Security') && class_exists('\App\Helpers\Auth')) { Security::logAudit(Auth::id(), 'CREATE_VENDOR', 'vendors', $newId); } } 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 Vendor & Unlinks Image Storage) // ======================================================== public function delete(): void { $this->validateCsrf(); $id = (int)($_POST['vendor_id'] ?? ($_POST['id'] ?? ($_GET['id'] ?? 0))); if ($id <= 0) { header('Location: /admin/vendors?error=invalid_id'); exit; } try { $db = Database::getConnection(); // Fetch image path before deletion $old = $db->prepare("SELECT image FROM vendors WHERE id = ?"); $old->execute([$id]); $oldImg = $old->fetchColumn(); // Delete database row $stmt = $db->prepare("DELETE FROM vendors WHERE id = ?"); $stmt->execute([$id]); // Database delete success hone par hi photo unlink karein if ($stmt->rowCount() > 0 && $oldImg) { $this->deleteVendorImage($oldImg); } if (class_exists('\App\Helpers\Security') && class_exists('\App\Helpers\Auth')) { Security::logAudit(Auth::id(), 'DELETE_VENDOR', 'vendors', $id); } header('Location: /admin/vendors?success=deleted'); exit; } catch (\Throwable $e) { error_log('[VENDOR_DELETE_ERROR] ' . $e->getMessage()); header('Location: /admin/vendors?error=db_error'); exit; } } // ======================================================== // 3. TOGGLE VERIFY (One-Click Verification Inversion) // ======================================================== public function toggleVerify(): void { $this->validateCsrf(); $id = (int)($_POST['vendor_id'] ?? ($_POST['id'] ?? ($_GET['id'] ?? 0))); if ($id <= 0) { header('Location: /admin/vendors?error=invalid_id'); exit; } try { $db = Database::getConnection(); $stmt = $db->prepare("UPDATE vendors SET is_verified = 1 - is_verified WHERE id = ?"); $stmt->execute([$id]); if (class_exists('\App\Helpers\Security') && class_exists('\App\Helpers\Auth')) { Security::logAudit(Auth::id(), 'TOGGLE_VENDOR_VERIFY', 'vendors', $id); } header('Location: /admin/vendors?success=status_updated'); exit; } catch (\Throwable $e) { error_log('[VENDOR_TOGGLE_ERROR] ' . $e->getMessage()); header('Location: /admin/vendors?error=db_error'); exit; } } // ======================================================== // PRIVATE HELPER: SAFE IMAGE UNLINKER // ======================================================== private function deleteVendorImage(?string $imagePath): void { if (empty($imagePath)) return; $base = dirname(__DIR__, 2); $paths = [ $base . '/public' . $imagePath, $base . $imagePath ]; foreach ($paths as $file) { if (file_exists($file) && is_file($file)) { @unlink($file); break; } } }
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
404 Not Found

404

Page Not Found

The requested page or endpoint does not exist on MIDEXA.

Return Home