&group= session_start(); require __DIR__ . '/includes/db.php'; if (!class_exists('ZipArchive')) { http_response_code(500); die('خاصية ZipArchive غير مفعّلة على الخادم.'); } $subjectId = (int)($_GET['subject'] ?? 0); $levelId = (int)($_GET['level'] ?? 0); $track = trim((string)($_GET['track'] ?? '')); $group = trim((string)($_GET['group'] ?? '')); if ($subjectId <= 0) { http_response_code(400); die('طلب غير صالح'); } // جلب المادة $sStmt = $pdo->prepare("SELECT * FROM subjects WHERE id=? AND active=1"); $sStmt->execute([$subjectId]); $subject = $sStmt->fetch(); if (!$subject) { http_response_code(404); die('المادة غير موجودة'); } // جلب المستوى (اختياري) $level = null; if ($levelId > 0) { $lStmt = $pdo->prepare("SELECT * FROM levels WHERE id=?"); $lStmt->execute([$levelId]); $level = $lStmt->fetch(); } // جلب الوثائق if ($track !== '') { $sql = "SELECT * FROM documents WHERE subject_id=? AND (level_id=? OR level_id IS NULL) AND (track IS NULL OR track='' OR track=?) ORDER BY type, created_at DESC"; $st = $pdo->prepare($sql); $st->execute([$subjectId, $levelId, $track]); } else { $sql = "SELECT * FROM documents WHERE subject_id=? AND (level_id=? OR level_id IS NULL) ORDER BY type, created_at DESC"; $st = $pdo->prepare($sql); $st->execute([$subjectId, $levelId]); } $docs = $st->fetchAll(); if (!$docs) { http_response_code(404); die('لا توجد ملفات لتنزيلها.'); } // اسم ملف الحزمة $safe = function ($s) { $s = preg_replace('/[^\p{L}\p{N}\-_ ]+/u', '', (string)$s); return trim($s) ?: 'file'; }; $pkgBase = $safe($subject['name']); if ($level) $pkgBase .= ' - ' . $safe($level['name']); if ($track) $pkgBase .= ' - ' . $safe($track); // إنشاء ZIP مؤقت $tmp = tempnam(sys_get_temp_dir(), 'pack_'); $zip = new ZipArchive(); if ($zip->open($tmp, ZipArchive::OVERWRITE) !== true) { http_response_code(500); die('تعذّر إنشاء الحزمة'); } // خريطة أسماء الأنواع $typeLabels = [ 'lesson' => 'دروس', 'exercise' => 'تمارين', 'solution' => 'حلول', 'exam' => 'امتحانات', 'summary' => 'ملخصات', 'other' => 'ملفات أخرى', ]; $indexHtml = ""; $indexHtml .= "" . htmlspecialchars($pkgBase) . ""; $indexHtml .= ""; $indexHtml .= "

📦 " . htmlspecialchars($pkgBase) . "

"; $indexHtml .= "

حزمة للعمل بدون إنترنت — " . count($docs) . " ملف. أُنشئت في " . date('Y-m-d H:i') . "

"; $byType = []; $added = 0; $missing = 0; foreach ($docs as $d) { $t = $d['type'] ?? 'other'; if (!isset($byType[$t])) $byType[$t] = []; $addFile = function ($relPath, $preferredName) use (&$zip, $t, $typeLabels, &$added, &$missing) { if (!$relPath) return null; $full = __DIR__ . '/' . $relPath; if (!file_exists($full)) { $missing++; return null; } $ext = pathinfo($relPath, PATHINFO_EXTENSION); $folder = $typeLabels[$t] ?? 'ملفات'; $inZip = $folder . '/' . $preferredName . ($ext ? '.' . $ext : ''); // تجنّب تكرار الاسم $i = 1; $orig = $inZip; while ($zip->locateName($inZip) !== false) { $pi = pathinfo($orig); $inZip = ($pi['dirname'] ? $pi['dirname'].'/' : '') . $pi['filename'] . '_' . (++$i) . (isset($pi['extension']) ? '.'.$pi['extension'] : ''); } $zip->addFile($full, $inZip); $added++; return $inZip; }; $title = $safe($d['title'] ?? ('doc-' . $d['id'])); $mainName = $addFile($d['file_path'] ?? '', $title); $solName = $addFile($d['correction_path'] ?? '', $title . ' - حل'); $byType[$t][] = [ 'title' => $d['title'] ?? '', 'main' => $mainName, 'sol' => $solName, ]; } foreach ($byType as $t => $rows) { $indexHtml .= "

" . htmlspecialchars($typeLabels[$t] ?? $t) . " (" . count($rows) . ")

"; } $indexHtml .= "

© منصة الدروس والاختبارات — حزمة Offline

"; $zip->addFromString('index.html', $indexHtml); $zip->addFromString('README.txt', "حزمة " . $pkgBase . "\n" . "عدد الملفات: " . $added . ($missing ? " (تعذّر إيجاد $missing)" : "") . "\n" . "افتح index.html لتصفح الحزمة بدون إنترنت.\n" ); $zip->close(); if ($added === 0) { @unlink($tmp); http_response_code(404); die('لا توجد ملفات صالحة للتنزيل.'); } $outName = $pkgBase . '.zip'; header('Content-Type: application/zip'); header('Content-Disposition: attachment; filename="' . rawurlencode($outName) . '"; filename*=UTF-8\'\'' . rawurlencode($outName)); header('Content-Length: ' . filesize($tmp)); header('Cache-Control: no-store'); readfile($tmp); @unlink($tmp); exit;