══════════ ارسال عکس و PDF توسط مشتری + دانلود در پنل مدیر ══════════

قوانین (هم در مرورگر و هم در سرور اعمال می‌شود)
  • مجاز: عکس (JPG، PNG، WebP، GIF)، PDF، Word/Excel/PowerPoint نو بدون ماکرو (docx، xlsx، pptx) و متن ساده (txt، UTF-8).
    هر چیز دیگر، حتی zip و doc/xls قدیمی، رد می‌شود. نوع فایل از محتوای واقعی‌اش تشخیص داده می‌شود، نه از پسوند.
  • فایل Office که ماکرو (vbaProject) یا شیء جاسازی‌شده (embeddings/ActiveX) داشته باشد رد می‌شود.
  • docx/xlsx/pptx/txt هیچ‌وقت داخل مرورگر باز نمی‌شوند؛ همیشه دانلود می‌شوند، و فقط نام و آیکن دارند (بدون بند انگشتی).
  • حداکثر ۱۰ فایل در هر درخواست، و مجموع حجم کمتر از ۱۵ مگابایت.
  • اگر یک فایل ایراد داشته باشد، کل درخواست ثبت نمی‌شود (چیز ناقصی ذخیره نمی‌شود) و پیام خطای روشن می‌آید.

مشتری
  • در فرم: دکمهٔ انتخاب یا کشیدن‌ورها کردن؛ بند انگشتی عکس‌ها، آیکن PDF، دکمهٔ حذف روی هر فایل،
    و شمارندهٔ «۳ از ۱۰ فایل · ۴٫۲ از ۱۵ مگابایت».
  • در صفحهٔ پیگیری (با کد پیگیری، فقط از همان مرورگری که درخواست را ثبت کرده): فایل‌های خودش با بند انگشتی،
    دانلود تکی و «دانلود همه (ZIP)».

مدیر (admin.html ← گفتگوی مشتری ← کادر درخواست‌ها)
  • بند انگشتی همهٔ فایل‌ها؛ کلیک روی بند انگشتی فایل اصلی را باز می‌کند.
  • «⬇ دانلود» زیر هر فایل: همان فایل اصلی، بایت‌به‌بایت.
  • تیک انتخاب + «دانلود انتخاب‌شده»: یک فایل = مستقیم، چند فایل = ZIP.
  • «دانلود همه (ZIP)» برای هر درخواست، و «همهٔ فایل‌های این مشتری (ZIP)» وقتی مشتری چند درخواست دارد.
  • ساخت ZIP نیاز به افزونهٔ zip هاست ندارد.

نصب
  ۱) همهٔ فایل‌ها را روی قبلی‌ها جایگزین کنید (api.php, common.js, form-engine.js, index.html, admin.html,
     style.css, form-packs.json, check.php, .htaccess و فایل جدید .user.ini — هر دو فایل مخفی‌اند، حتماً آپلود شوند).
  ۲) هاست باید upload_max_filesize ≥ 16M و post_max_size ≥ 20M باشد. .htaccess و .user.ini همین را درخواست می‌کنند؛
     اگر روی هاست شما اثر نکرد، از cPanel ← Select PHP Version ← Options بگذارید.
  ۳) /cafenetakbari/check.php را باز کنید: سقف آپلود و افزونهٔ GD را نشان می‌دهد. بعد از بررسی حذفش کنید.

نکته‌ها
  • بند انگشتی عکس‌ها با افزونهٔ GD ساخته و کش می‌شود (data/req-files/th-*.jpg). اگر GD نبود، به‌جای عکس آیکن نشان داده می‌شود
    و کارها بقیه درست است.
  • بند انگشتی PDF فعلاً آیکن «PDF» است (رندر صفحهٔ اول PDF روی هاست اشتراکی معمولاً ممکن نیست).
  • فایل‌هایی که قبل از این نسخه با پسوند doc/docx/zip ثبت شده بودند هرگز ذخیره نشده بودند (سرور قبلاً هم رد می‌کرد).
  • این کد را من اجرا نکرده‌ام (روی سیستم من PHP نبود). منطق ZIP را جداگانه با پایتون آزمودم و جاوااسکریپت‌ها را
    از نظر نحو بررسی کردم، اما سناریوی کامل را یک بار روی هاست تست کنید (فهرست پایین).

آزمون پیشنهادی
  ۱) ثبت درخواست با ۳ عکس و ۱ PDF و ۱ docx ← در پنل مدیر هر ۴ فایل با بند انگشتی دیده شود و دانلود تکی همان فایل باشد.
  ۲) انتخاب ۱۱ فایل ← پیام حداکثر ۱۰ فایل.   ۳) فایل zip یا docx ← رد شود.
  ۴) چند عکس جمعاً بیش از ۱۵ مگابایت ← رد شود.   ۵) دانلود همه (ZIP) باز شود و فایل‌ها سالم باشند.


══════════ تب «📋 فرم‌ها» در پنل مدیریت ══════════
  • همهٔ بسته‌های فرم (form-packs.json) در یک تب جدا: نام بسته، تعداد فیلد، جدول فیلدها (نوع، اجباری، توضیح)
    و دکمهٔ «پیش‌نمایش فرم». جستجو بین نام بسته‌ها و فیلدها. فیلدهای تکی هم پایین صفحه دیده می‌شوند.
  • فعلاً فقط نمایشی است؛ بسته‌ها با ویرایش فایل form-packs.json عوض می‌شوند. استفاده از آن‌ها همان قبل است:
    در تب «خدمت‌ها» دکمهٔ «+ نام بسته».
