query("SELECT * FROM categories ORDER BY sort_order")->fetchAll(); $services = $pdo->query("SELECT * FROM services")->fetchAll(); $sizes = $pdo->query("SELECT * FROM sizes")->fetchAll(); $error = ''; $success = ''; if ($_SERVER['REQUEST_METHOD'] === 'POST') { $csrf_valid = true; if (function_exists('verify_csrf')) { if (!verify_csrf($_POST['csrf_token'] ?? '')) { $error = 'خطای امنیتی: توکن نامعتبر است.'; $csrf_valid = false; } } if ($csrf_valid) { $title = clean($_POST['title'] ?? ''); $description = clean($_POST['description'] ?? ''); $category_id = $_POST['category_id'] ? (int)$_POST['category_id'] : null; $type = $_POST['type'] ?? 'print'; // قیمت محصول ساده $simple_price = ($type === 'simple') ? (float)($_POST['simple_price'] ?? 0) : 0; $download_price = ($type === 'download') ? (float)($_POST['download_price'] ?? 0) : 0; $pricing_model = $_POST['pricing_model'] ?? 'area_based'; $size_mode = $_POST['size_mode'] ?? 'free'; $locked_size_id = (!empty($_POST['locked_size_id'])) ? (int)$_POST['locked_size_id'] : null; $size_constraint_type = $_POST['size_constraint_type'] ?? 'none'; $max_free_width_cm = null; $max_free_height_cm = null; // تنظیمات جدید مدل $enable_model_selection = isset($_POST['enable_model_selection']) ? 1 : 0; $model_selection_mandatory = isset($_POST['model_selection_mandatory']) ? 1 : 0; if ($type === 'print' && $size_mode === 'free' && $size_constraint_type !== 'none') { if ($size_constraint_type === 'width' || $size_constraint_type === 'both') { $max_free_width_cm = (float)($_POST['max_free_width_cm'] ?? 0); } if ($size_constraint_type === 'height' || $size_constraint_type === 'both') { $max_free_height_cm = (float)($_POST['max_free_height_cm'] ?? 0); } } $multi_size_prices = null; if ($type === 'print' && $size_mode === 'multi' && !empty($_POST['multi_sizes'])) { $tempPrices = []; foreach ($_POST['multi_sizes'] as $sid) { $pSingle = (float)($_POST['price_single_' . $sid] ?? 0); $pDouble = (float)($_POST['price_double_' . $sid] ?? 0); $tempPrices[$sid] = ['single' => $pSingle, 'double' => $pDouble]; } $multi_size_prices = json_encode($tempPrices); } $dpi_mode = $_POST['dpi_mode'] ?? 'range'; $min_dpi = (int)($_POST['min_dpi'] ?? 300); $max_dpi = $dpi_mode === 'range' ? (int)($_POST['max_dpi'] ?? 600) : null; $exact_dpi = $dpi_mode === 'exact' ? (int)$_POST['exact_dpi'] ?? 300 : null; $require_cmyk = isset($_POST['require_cmyk']) ? 1 : 0; $production_days = (int)($_POST['production_days'] ?? 7); $max_file_size_mb = (int)($_POST['max_file_size_mb'] ?? 10); $status = isset($_POST['status']) ? 1 : 0; $allow_upload = isset($_POST['allow_upload']) ? 1 : 0; $is_four_file_mode = isset($_POST['is_four_file_mode']) ? 1 : 0; $enable_design_service = isset($_POST['enable_design_service']) ? 1 : 0; $max_design_ref_size_mb = (int)($_POST['max_design_ref_size_mb'] ?? 5); $has_double_side = isset($_POST['has_double_side']) ? 1 : 0; $print_sides = $has_double_side ? 'double' : 'single'; $single_side_price = $double_side_price = $single_side_price_sqcm = $double_side_price_sqcm = 0; if ($type === 'simple') { $single_side_price = $simple_price; $pricing_model = 'fixed'; $size_mode = 'fixed'; $allow_upload = 0; $print_sides = 'single'; } elseif ($type === 'print' && $has_double_side) { if ($pricing_model === 'fixed') { $single_side_price = (float)($_POST['single_side_price'] ?? 0); $double_side_price = (float)($_POST['double_side_price'] ?? 0); } else { $single_side_price_sqcm = (float)($_POST['single_side_price_sqcm'] ?? 0); $double_side_price_sqcm = (float)($_POST['double_side_price_sqcm'] ?? 0); } } elseif ($type === 'print') { if ($pricing_model === 'fixed') $single_side_price = (float)($_POST['simple_price'] ?? 0); else $single_side_price_sqcm = (float)($_POST['simple_price_sqcm'] ?? 0); $double_side_price = $double_side_price_sqcm = 0; } if (!$title) { $error = 'عنوان الزامی است.'; } elseif (!isset($_FILES['image']) || $_FILES['image']['error'] !== UPLOAD_ERR_OK) { $error = 'آپلود تصویر شاخص الزامی است.'; } elseif ($type === 'download' && $download_price <= 0) { $error = 'برای محصول دانلودی قیمت تعیین کنید.'; } elseif ($type === 'simple' && $simple_price <= 0) { $error = 'برای محصول ساده قیمت تعیین کنید.'; } else { $image = upload_file('image', '../uploads/'); if (!$image) { $error = 'خطا در آپلود تصویر.'; } else { $slug = make_slug($title); try { $pdo->beginTransaction(); $stmt = $pdo->prepare(" INSERT INTO products (title, slug, description, category_id, type, download_price, pricing_model, price_per_sqcm, single_side_price, double_side_price, single_side_price_sqcm, double_side_price_sqcm, double_side_multiplier, size_mode, size_constraint_type, max_free_width_cm, max_free_height_cm, locked_size_id, allow_user_size, min_dpi, max_dpi, exact_dpi, dpi_mode, require_cmyk, production_days, status, allow_upload, is_four_file_mode, enable_design_service, enable_model_selection, model_selection_mandatory, multi_size_prices, print_sides, image, size_tolerance_mm, max_file_size_mb, max_design_ref_size_mb) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) "); $stmt->execute([ $title, $slug, $description, $category_id, $type, $download_price, $pricing_model, 0.00, $single_side_price, $double_side_price, $single_side_price_sqcm, $double_side_price_sqcm, 1.00, $size_mode, $size_constraint_type, $max_free_width_cm, $max_free_height_cm, $locked_size_id, 1, $min_dpi, $max_dpi, $exact_dpi, $dpi_mode, $require_cmyk, $production_days, $status, $allow_upload, $is_four_file_mode, $enable_design_service, $enable_model_selection, $model_selection_mandatory, $multi_size_prices, $print_sides, $image, 2.0, $max_file_size_mb, $max_design_ref_size_mb ]); $product_id = $pdo->lastInsertId(); // ⭐ هندل کردن آپلود مدلهای انتخابی - نسخه اصلاح شده با نام اصلی فایل if (isset($_FILES['model_files']) && !empty($_FILES['model_files']['name'][0])) { $modelFiles = $_FILES['model_files']; foreach ($modelFiles['name'] as $key => $originalName) { if ($modelFiles['error'][$key] !== UPLOAD_ERR_OK) continue; $ext = strtolower(pathinfo($originalName, PATHINFO_EXTENSION)); if (!in_array($ext, ['jpg', 'jpeg', 'png', 'webp'])) continue; // پاک کردن نام فایل (فقط حروف، اعداد، خط تیره و زیرخط مجاز) $baseName = pathinfo($originalName, PATHINFO_FILENAME); $cleanName = preg_replace('/[^a-zA-Z0-9\-_]/', '_', $baseName); // اگر خالی شد، یه نام پیشفرض بذار if (empty($cleanName)) { $cleanName = 'model_' . time(); } $finalFileName = $cleanName . '.' . $ext; $finalCode = $cleanName; // چک کردن تکراری بودن - اضافه کردن عدد در صورت نیاز $counter = 1; $originalCleanName = $cleanName; while (file_exists('../uploads/' . $finalFileName)) { $finalCode = $originalCleanName . '_' . $counter; $finalFileName = $finalCode . '.' . $ext; $counter++; } if (move_uploaded_file($modelFiles['tmp_name'][$key], '../uploads/' . $finalFileName)) { $stmtM = $pdo->prepare("INSERT INTO product_model_images (product_id, file_path, image_code) VALUES (?, ?, ?)"); $stmtM->execute([$product_id, $finalFileName, $finalCode]); } } } if ($type === 'download' && !empty($_POST['download_titles'])) { $titles = $_POST['download_titles']; $storage_types = $_POST['storage_types'] ?? []; $private_filenames = $_POST['private_filenames'] ?? []; $external_urls = $_POST['external_urls'] ?? []; foreach ($titles as $key => $dl_title) { $dl_title = clean($dl_title); if (empty($dl_title)) continue; $storage_type = $storage_types[$key] ?? 'local'; if ($storage_type === 'local' && !empty($_FILES['download_files']['name'][$key])) { $dlDir = '../uploads/downloads/'; if (!is_dir($dlDir)) mkdir($dlDir, 0755, true); $file = $_FILES['download_files']; if ($file['error'][$key] === UPLOAD_ERR_OK) { $ext = strtolower(pathinfo($file['name'][$key], PATHINFO_EXTENSION)); if (in_array($ext, ['zip','rar','pdf','jpg','png','mp4','mp3','psd','ai','doc','docx','ppt','pptx'])) { $newName = 'dl_' . uniqid() . '.' . $ext; if (move_uploaded_file($file['tmp_name'][$key], $dlDir . $newName)) { $stmtDl = $pdo->prepare(" INSERT INTO product_downloads (product_id, title, file_path, storage_type, sort_order) VALUES (?, ?, ?, 'local', ?) "); $stmtDl->execute([$product_id, $dl_title, $newName, $key]); } } } } elseif ($storage_type === 'private' && !empty($private_filenames[$key])) { $filename = basename(clean($private_filenames[$key])); $privatePath = '../uploads/downloads/private/' . $filename; if (file_exists($privatePath)) { $stmtDl = $pdo->prepare(" INSERT INTO product_downloads (product_id, title, file_path, storage_type, sort_order) VALUES (?, ?, ?, 'private', ?) "); $stmtDl->execute([$product_id, $dl_title, $filename, $key]); } } elseif ($storage_type === 'external' && !empty($external_urls[$key])) { $url = clean($external_urls[$key]); $stmtDl = $pdo->prepare(" INSERT INTO product_downloads (product_id, title, download_url, storage_type, sort_order) VALUES (?, ?, ?, 'external', ?) "); $stmtDl->execute([$product_id, $dl_title, $url, $key]); } } } if ($type === 'download' && !empty($_POST['edu_titles'])) { $edu_titles = $_POST['edu_titles']; $edu_types = $_POST['edu_types'] ?? []; $edu_storage_types = $_POST['edu_storage_types'] ?? []; $edu_private_filenames = $_POST['edu_private_filenames'] ?? []; $edu_external_urls = $_POST['edu_external_urls'] ?? []; foreach ($edu_titles as $key => $edu_title) { $edu_title = clean($edu_title); if (empty($edu_title)) continue; $file_type = $edu_types[$key] ?? 'video'; $storage_type = $edu_storage_types[$key] ?? 'local'; $file_path = null; $download_url = null; if ($storage_type === 'local' && !empty($_FILES['edu_files']['name'][$key])) { $eduDir = '../uploads/educational/'; if (!is_dir($eduDir)) mkdir($eduDir, 0755, true); $file = $_FILES['edu_files']; if ($file['error'][$key] === UPLOAD_ERR_OK) { $ext = strtolower(pathinfo($file['name'][$key], PATHINFO_EXTENSION)); $allowedExts = []; if ($file_type === 'video') { $allowedExts = ['mp4', 'webm', 'mov']; } elseif ($file_type === 'audio') { $allowedExts = ['mp3', 'wav', 'ogg']; } elseif ($file_type === 'pdf') { $allowedExts = ['pdf']; } if (in_array($ext, $allowedExts)) { $newName = 'edu_' . uniqid() . '.' . $ext; if (move_uploaded_file($file['tmp_name'][$key], $eduDir . $newName)) { $file_path = $newName; } } } } elseif ($storage_type === 'private' && !empty($edu_private_filenames[$key])) { $filename = basename(clean($edu_private_filenames[$key])); $privatePath = '../uploads/educational/private/' . $filename; if (file_exists($privatePath)) { $file_path = $filename; } } elseif ($storage_type === 'external' && !empty($edu_external_urls[$key])) { $download_url = clean($edu_external_urls[$key]); } if ($file_path || $download_url) { $stmtEdu = $pdo->prepare(" INSERT INTO product_educational_files (product_id, title, file_path, download_url, storage_type, file_type, sort_order) VALUES (?, ?, ?, ?, ?, ?, ?) "); $stmtEdu->execute([ $product_id, $edu_title, $file_path, $download_url, $storage_type, $file_type, $key ]); } } } if (!empty($_FILES['gallery_images']['name'][0])) { $files = $_FILES['gallery_images']; foreach ($files['name'] as $key => $name) { if ($files['error'][$key] === UPLOAD_ERR_OK) { $ext = strtolower(pathinfo($name, PATHINFO_EXTENSION)); if (in_array($ext, ['jpg','jpeg','png','webp'])) { $newName = uniqid('gal_') . '.' . $ext; if (move_uploaded_file($files['tmp_name'][$key], '../uploads/' . $newName)) { $stmtMedia = $pdo->prepare("INSERT INTO product_media (product_id, type, file_path, sort_order) VALUES (?, 'image', ?, ?)"); $stmtMedia->execute([$product_id, $newName, $key]); } } } } } if (!empty($_FILES['gallery_videos']['name'][0])) { $files = $_FILES['gallery_videos']; foreach ($files['name'] as $key => $name) { if ($files['error'][$key] === UPLOAD_ERR_OK) { $ext = strtolower(pathinfo($name, PATHINFO_EXTENSION)); if (in_array($ext, ['mp4','webm','mov'])) { $newName = uniqid('vid_') . '.' . $ext; if (move_uploaded_file($files['tmp_name'][$key], '../uploads/' . $newName)) { $stmtMedia = $pdo->prepare("INSERT INTO product_media (product_id, type, file_path, sort_order) VALUES (?, 'video', ?, ?)"); $stmtMedia->execute([$product_id, $newName, $key]); } } } } } if (!empty($_POST['services'])) { $srv_stmt = $pdo->prepare("INSERT INTO product_services (product_id, service_id) VALUES (?, ?)"); foreach ($_POST['services'] as $srv_id) $srv_stmt->execute([$product_id, (int)$srv_id]); } $pdo->commit(); $success = '✅ محصول با موفقیت اضافه شد.'; } catch (Exception $e) { $pdo->rollBack(); @unlink('../uploads/' . $image); $error = 'خطا در ثبت محصول: ' . $e->getMessage(); } } } } } $page_title = 'افزودن محصول جدید'; include 'header.php'; ?>