# راهنمای تغییرات (Patch Notes)

فایل‌های تغییریافته: `send.php`، `order_process.php`، `index.php`، `orders.php`.
همه با `php -l` بدون خطای نحوی تأیید شده‌اند.

---

## ۰) رفع علت اصلی «هنگ کردن سرور» — `send.php` (بحرانی 🔴)

### ریشه مشکل
این فایل هیچ قفلی برای جلوگیری از اجرای هم‌زمان نداشت و در هر اجرا تا **۱۰۰۰ سفارش**
را پشت‌سرهم بررسی می‌کرد؛ برای هرکدام یک تماس API با `jap_post()` که تا **۳۰ ثانیه**
می‌تواند طول بکشد. یعنی در بدترین حالت یک اجرای این فایل می‌توانست **ساعت‌ها** طول بکشد.
اگر کرون هر ۱ تا ۵ دقیقه این فایل را صدا می‌زد (حالت معمول)، پیش از پایان یک اجرا،
اجرای بعدی هم شروع می‌شد. این پروسه‌های PHP روی هم انباشته می‌شدند و هرکدام یک اتصال
دیتابیس باز نگه می‌داشتند — تا جایی که ظرفیت سرور (PHP-FPM workers / اتصالات MySQL)
پر می‌شد و **کل سرور هنگ می‌کرد**، نه فقط ربات.

### تغییرات
1. **قفل فایلی (`send.lock`)** — دقیقاً مشابه قفل موجود در `tron_check_cron.php` و
   `cron-jobs.php`؛ اگر اجرای قبلی کمتر از ۲ دقیقه پیش شروع شده باشد، اجرای جدید فوراً
   خارج می‌شود.
2. **سقف زمانی واقعی (۴۵ ثانیه)** — داخل حلقه، اگر از زمان شروع اسکریپت بیش از ۴۵ ثانیه
   گذشته باشد، پردازش باقی‌مانده به اجرای بعدی کرون واگذار می‌شود؛ اسکریپت هرگز بیشتر از
   این مدت طول نمی‌کشد، حتی اگر همه‌ی تماس‌های API کند/timeout باشند.
3. **کاهش تعداد سفارش هر اجرا از ۱۰۰۰ به ۴۰** — عددی که با سقف زمانی بالا هم‌خوانی دارد.

### ⚠️ توصیه مهم
کرون این فایل را طوری تنظیم کنید که فاصله‌ی دو اجرا حداقل ۱ دقیقه باشد (مثلاً `* * * * *`).
اگر تعداد سفارش‌های در انتظار شما زیاد است و ۴۰ تا در هر دقیقه کافی نیست، به‌جای افزایش
دوباره‌ی این عدد به مقادیر بزرگ، فاصله‌ی کرون را کمتر کنید (مثلاً هر ۳۰ ثانیه، اگر هاست
اجازه می‌دهد) تا هر اجرا کوتاه و امن باقی بماند.

## ۰-۱) رفع ناهماهنگی قفل و مهلت اجرا — `cron-jobs.php` (بحرانی 🔴)

### ریشه مشکل
این کرون (بررسی واریزهای ۱۳ ارز دیجیتال مختلف) از قبل هم یک قفل فایلی داشت، اما یک
ناسازگاری خطرناک در اعداد وجود داشت: خودِ اسکریپت با `set_time_limit(900)` مجاز بود تا
**۱۵ دقیقه** اجرا شود، ولی قفل فقط تا **۱۰ دقیقه (۶۰۰ ثانیه)** معتبر شمرده می‌شد. یعنی
بین دقیقه‌ی ۱۰ تا ۱۵ یک اجرای کاملاً قانونی و هنوز درحال‌کار، به اشتباه «قدیمی» تشخیص داده
می‌شد و کرون بعدی یک اجرای دوم و هم‌زمان شروع می‌کرد — دقیقاً همان الگوی انباشته‌شدن
پروسه‌ها که باعث هنگ سرور می‌شود (مشابه باگ `send.php`)، این‌بار به‌خاطر ناهماهنگی زمان‌ها
نه نبودِ قفل. با توجه به طراحی این فایل (۱۳ ارز، `usleep` بین هر آدرس برای رعایت
rate-limit ارائه‌دهنده‌های API)، این اسکریپت واقعاً ممکن است به مرزهای ۱۰ تا ۱۵ دقیقه نزدیک شود.

### تغییرات
1. مهلت اعتبار قفل از ۶۰۰ به ۹۵۰ ثانیه افزایش یافت (کمی بیشتر از `set_time_limit(900)`).
2. یک «بودجه‌ی زمانی نرم» (۸۰۰ ثانیه) اضافه شد که داخل تمام حلقه‌های بررسی کیف‌پول
   (TRX، BNB، و ۱۱ ارز دیگر) چک می‌شود؛ با رسیدن به این بودجه، اسکریپت به‌جای اینکه توسط
   PHP به‌طور ناگهانی kill شود، خودش تمیز متوقف می‌شود و باقی‌مانده‌ی کیف‌پول‌ها را به
   اجرای بعدی کرون واگذار می‌کند.

---

### ریشه مشکل (از روی `send_log.txt`)
پنل API برای **هر** سفارش پاسخ `{"error":"Incorrect order ID"}` می‌داد. یعنی آیدی سفارش‌های جدول `list`
متعلق به کلید/پنل فعلی نبودند — پنل/کلید عوض شده بود. چون `$res['status']` هیچ‌وقت ست نمی‌شد،
هیچ پیامی ارسال نمی‌شد و ردیف‌ها هم حذف نمی‌شدند → حلقه بی‌نهایت چک شدن.

### تغییرات
1. **استعلام چندپنلی (`resolve_order_status`)** — وضعیت هر سفارش روی همهٔ پنل‌های دارای کلید امتحان می‌شود.
2. **fallback متنی (`notify_order`)** — اگر `sendphoto` شکست بخورد (عکس `19like.ir` در دسترس نباشد)، پیام متنی ارسال می‌شود.
3. **مدیریت `lastcheck_at` تهی** — سفارش‌های تازه فوراً انتخاب می‌شوند.
4. **توقف حلقه بی‌نهایت** — پس از ۵۰ تلاش ناموفق، سفارش `Unresolved` می‌شود.

---

## ۲) هوشمندسازی بخش ➕ New Order — `order_process.php`

جریان سه‌مرحله‌ای شد: **انتخاب پلتفرم → انتخاب دسته → انتخاب سرویس**.
مثلاً با زدن «✈️ Telegram» فقط دسته‌های تلگرامی نمایش داده می‌شوند (Members، Views، Reactions، Comments، Auto Views، ...).
پلتفرم‌ها به‌صورت خودکار از روی نام دسته‌های جدول `button` تشخیص داده می‌شوند — بدون تغییر دیتابیس.
توابع جدید: `bot_platforms()`، `bot_detect_platform()`، `displayPlatforms()`، `displayCategoriesForPlatform()`.
هندلرهای جدید: `pf_{platform}`، `pfcat_{platform}_{page}`، `back_to_platforms`.

---

## ۳) رفع نمایش بخش 📊 My Ads (وب اپ) — `index.php` و `orders.php`

### مشکل‌ها
1. **دامنهٔ اشتباه دکمهٔ وب‌اپ:** همهٔ دکمه‌های «View Orders / View all orders» به
   `https://19like.ir/19/4/bot2/orders.php` اشاره می‌کردند، در حالی که کد روی `telmember.ir` است → صفحه باز نمی‌شد/قدیمی بود.
2. **پنل API اشتباه و هاردکد در `orders.php`:** فایل وب‌اپ از کلید/پنل JAP هاردکد
   (`justanotherpanel.com` با کلید `47a58bf1...`) استفاده می‌کرد که با پنل ثبت سفارش‌ها فرق داشت
   → همهٔ سفارش‌ها «API Error» نشان داده می‌شدند.
3. **کارت داخل چت (My Ads) در `index.php`** فقط روی یک پنل (`$apiurl`) استعلام می‌کرد.

### تغییرات
- **`index.php`** — دو دکمهٔ وب‌اپ به `https://telmember.ir/19/4/bot2/orders.php` اصلاح شد.
- **`order_process.php`** — دکمهٔ وب‌اپ «View Orders 📊» نیز به `telmember.ir` اصلاح شد.
- **`orders.php`** — به‌جای کلید/پنل هاردکد، حالا روی **همهٔ پنل‌ها** استعلام دسته‌جمعی (bulk) می‌زند و
  نتایج را ادغام می‌کند؛ هر سفارش روی پنلی که واقعاً مالک آن است resolve می‌شود
  (`bulkFetchFromPanel` + `bulkFetchOrderStatuses` بازنویسی شد).
- **`index.php` (کارت My Ads داخل چت)** — استعلام وضعیت چندپنلی شد تا با وب‌اپ هماهنگ باشد.

### ⚠️ نکتهٔ مهم پیکربندی
لیست پنل‌ها در `orders.php` (`$STATUS_PANELS`) و در بلوک My Ads فایل `index.php` به‌صورت محلی تعریف شده‌اند.
اگر کلید یا آدرس هر پنل را در `config.php` تغییر دادید، همان‌ها را در این دو محل هم به‌روزرسانی کنید
(یا برای فعال شدن سقف تلاش در send.php این ستون را بسازید):

```sql
ALTER TABLE `list` ADD COLUMN `tries` INT NOT NULL DEFAULT 0;
```

> مهم‌ترین کار: مطمئن شوید کلید/پنل API واقعی که سفارش‌ها روی آن ثبت می‌شوند، در این لیست‌ها وجود دارد.
