# راهنمای نصب پرمی‌استار

این راهنما دو سناریو را پوشش می‌دهد: **هاست اشتراکی / cPanel** و **محیط توسعه محلی**.
کل نصب از طریق نصب‌کننده وب انجام می‌شود و نیازی به Composer، npm یا اجرای دستی SQL نیست.

---

## ۱. پیش‌نیازها

| مورد | حداقل | توضیح |
| --- | --- | --- |
| PHP | ۸٫۱ | توصیه: ۸٫۲ یا ۸٫۳ |
| پایگاه داده | MariaDB 10.3+ / MySQL 5.7+ | با کاربری که اجازه `CREATE TABLE` و `INSERT` داشته باشد |
| وب‌سرور | Apache + `mod_rewrite` | Nginx هم با تنظیم `try_files` کار می‌کند (بخش ۷) |
| HTTPS | توصیه قوی | برای درگاه پرداخت و مرکز امنیت لازم است |

**افزونه‌های ضروری PHP** (در گام ۲ نصب‌کننده بررسی می‌شوند):
`pdo`, `pdo_mysql`, `mbstring`, `curl`, `json`, `openssl`, `fileinfo`, `session`, `ctype`, `tokenizer`

**اختیاری اما توصیه‌شده:** `gd` (پردازش تصویر)، `intl`، `zip` (پشتیبان‌گیری)،
`sodium` و `argon2id` (هش قوی‌تر رمزها؛ در صورت نبود، `bcrypt` استفاده می‌شود).

> نبود `intl` مشکلی ایجاد نمی‌کند: تقویم جلالی به‌صورت داخلی و بدون وابستگی پیاده‌سازی شده است.

---

## ۲. آپلود فایل‌ها

۱. همه محتوای پروژه را آپلود کنید:
   `app/`, `bootstrap/`, `config/`, `database/`, `public/`, `resources/`, `routes/`, `storage/`, `docs/`, `tests/`, `.htaccess`
2. **document root** دامنه را روی پوشه `public` قرار دهید (cPanel → Domains → document root).
   - اگر این ممکن نیست، فایل `.htaccess` ریشه همه درخواست‌ها را به `public/` بازنویسی می‌کند؛
     در این حالت آدرس سایت همچنان بدون `/public` کار می‌کند.
3. فایل `.env` را آپلود **نکنید**؛ نصب‌کننده آن را می‌سازد. اگر از قبل وجود دارد، حذفش کنید.

---

## ۳. دسترسی‌های لازم (Permissions)

پوشه‌های زیر باید برای کاربر وب‌سرور **قابل نوشتن** باشند:

```
storage/            و زیرپوشه‌های logs, cache, backups, private
public/uploads/     و زیرپوشه‌های products, pages
config/             (فقط در زمان نصب، برای ساخت .env)
ریشه پروژه          (فقط در زمان نصب، برای ساخت .env و storage/installed.lock)
```

روی cPanel معمولاً `755` برای پوشه‌ها و `644` برای فایل‌ها کافی است؛ در صورت نیاز `775`.

```bash
# در صورت دسترسی SSH
find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;
chmod -R 775 storage public/uploads
```

> **پس از پایان نصب**، دسترسی نوشتن `config/` و ریشه را به `755` برگردانید (`.env` روی `640` بماند).

---

## ۴. ساخت پایگاه داده

در cPanel → **MySQL® Databases**:

1. یک پایگاه داده بسازید (مثلاً `user_permistar`).
2. یک کاربر با رمز قوی بسازید.
3. کاربر را به پایگاه داده اضافه کنید و دسترسی **All Privileges** بدهید.
4. اطلاعات را یادداشت کنید: `DB_HOST` (معمولاً `localhost`)، `DB_PORT` (معمولاً `3306`)،
   `DB_NAME`، `DB_USER`، `DB_PASS`.

> جدول‌ها توسط نصب‌کننده ساخته می‌شوند؛ نیازی به import دستی `database/migrations/001_create_schema.sql` نیست.

---

## ۵. اجرای نصب‌کننده

به این آدرس بروید:

```
https://your-domain.com/install
```

| گام | عنوان | چه چیزی لازم است |
| --- | --- | --- |
| ۱ | خوش‌آمد | مرور کلی و شروع |
| ۲ | پیش‌نیازها | بررسی نسخه PHP، افزونه‌ها و پوشه‌های قابل نوشتن |
| ۳ | پایگاه داده | `host`, `port`, `name`, `user`, `password` + تست اتصال |
| ۴ | وب‌سایت | نام سایت، آدرس (URL)، اختلاف زمانی (پیش‌فرض `12600` = تهران)، واحد پول (تومان) |
| ۵ | مدیر کل | نام، نام خانوادگی، موبایل (نام کاربری ورود)، ایمیل و رمز عبور قوی |
| ۶ | سرویس‌ها | مرچنت کد زرین‌پال (+حالت sandbox)، نام کاربری/رمز/شماره ارسال ملی‌پیامک |
| ۷ | نصب | ساخت `.env`، اجرای مهاجرت‌ها، داده‌های اولیه، ساخت حساب مدیر، نوشتن قفل نصب |
| ۸ | پایان | گزارش نصب + ورود به پنل |

نکات:

- **گام ۶ اختیاری است.** بدون مرچنت کد، پرداخت به حالت «در انتظار» می‌ماند و از پنل قابل تکمیل است.
  بدون اطلاعات پیامک، سرویس در **حالت آزمایشی** کار می‌کند و کد OTP در پاسخ/لاگ نمایش داده می‌شود.
- پس از گام ۷، فایل `storage/installed.lock` ساخته می‌شود و `/install` از آن پس فقط صفحه
  «قفل شده» را نشان می‌دهد (کد ۴۰۳). برای نصب مجدد باید هم `.env` و هم `storage/installed.lock` حذف شوند.

---

## ۶. اقدامات پس از نصب

1. **ورود به پنل:** `https://your-domain.com/admin/login` با موبایل و رمزی که در گام ۵ ساختید.
2. پنل مدیریت → **تنظیمات سایت**: آدرس سایت، اطلاعات تماس، متن فوتر و وضعیت ثبت‌نام را نهایی کنید.
3. پنل مدیریت → **تنظیمات پرداخت**: مرچنت کد واقعی زرین‌پال را وارد و حالت sandbox را خاموش کنید؛
   آدرس بازگشت (callback) را در زرین‌پال هم ثبت کنید:
   `https://your-domain.com/payment/zarinpal/callback`
4. پنل مدیریت → **تنظیمات پیامک**: اطلاعات ملی‌پیامک را وارد و «حالت آزمایشی» را خاموش کنید،
   سپس با دکمه «ارسال پیامک آزمایشی» نتیجه را ببینید.
5. پنل مدیریت → **مرکز امنیت**: ۹ بررسی امنیتی را سبز کنید (HTTPS، قفل نصب‌کننده، `.htaccess` آپلودها،
   خاموش بودن debug، فعال بودن OTP و درگاه واقعی، اجازه IP مدیران).
6. پنل مدیریت → **مدیران و نقش‌ها**: در صورت نیاز حساب پشتیبان بسازید؛ دسترسی‌ها را حداقلی انتخاب کنید.
7. پنل مدیریت → **پشتیبان‌ها**: اولین پشتیبان پایگاه داده را بسازید و **خارج از هاست** هم نگهداری کنید.
8. `APP_DEBUG=false` در `.env` (نصب‌کننده در حالت عادی همین را می‌نویسد).
9. در صورت تمایل، پوشه‌های `docs/` و `tests/` را از هاست حذف کنید (برای اجرای سایت لازم نیستند).

---

## ۷. Nginx (اختیاری)

اگر به‌جای Apache از Nginx استفاده می‌کنید، `.htaccess` بی‌اثر است؛ این پیکربندی را استفاده کنید:

```nginx
server {
    listen 443 ssl http2;
    server_name your-domain.com;
    root /home/user/permistar/public;
    index index.php;

    location / { try_files $uri $uri/ /index.php?$query_string; }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    # هرگز این مسیرها سرو نشوند
    location ~ ^/(storage|config|app|database|resources|routes|bootstrap)/ { deny all; }
    location ~ /\.(env|htaccess|git) { deny all; }
    location ~ ^/uploads/.*\.(php|phtml|phar|cgi|pl|py|sh)$ { deny all; }
}
```

---

## ۸. محیط توسعه محلی

```bash
cd permistar
php -S 0.0.0.0:8123 -t public public/router.php
```

سپس `http://127.0.0.1:8123/install` را باز کنید. برای پایگاه داده می‌توانید از MySQL/MariaDB محلی
یا Docker استفاده کنید:

```bash
docker run --name permistar-db -e MARIADB_ROOT_PASSWORD=secret \
  -e MARIADB_DATABASE=permistar -p 3306:3306 -d mariadb:11
```

اجرای تست‌ها:

```bash
php tests/run.php
```

---

## ۹. رفع اشکال

| نشانه | علت احتمالی | راه‌حل |
| --- | --- | --- |
| صفحه سفید یا خطای ۵۰۰ | خطای PHP | `storage/logs/php-error.log` را ببینید؛ `APP_DEBUG=true` موقتاً |
| «برخی پیش‌نیازها برآورده نشده‌اند» | نبود افزونه یا پوشه غیرقابل نوشتن | در cPanel → Select PHP Version افزونه‌ها را فعال و دسترسی‌ها را اصلاح کنید |
| خطای اتصال پایگاه داده | host/port/نام کاربری اشتباه | در هاست اشتراکی `localhost` و پورت `3306`؛ نام کاربری شامل پیشوند cPanel است |
| `/install` صفحه «قفل شده» می‌دهد | فایل `storage/installed.lock` وجود دارد | برای نصب مجدد، آن را به‌همراه `.env` حذف کنید |
| خطای ۴۱۹ روی فرم‌ها | توکن CSRF منقضی/جلسه بسته | صفحه را رفرش کنید؛ `SESSION_LIFETIME` را بررسی کنید |
| خطای ۴۰۴ روی assetها | document root اشتباه | ریشه باید پوشه `public` باشد |
| کد OTP پیامک نمی‌شود | حالت آزمایشی روشن است | پنل → تنظیمات پیامک → «حالت آزمایشی» را خاموش و تست ارسال بزنید |
| پرداخت انجام نمی‌شود | مرچنت کد خالی یا sandbox روشن | پنل → تنظیمات پرداخت؛ آدرس callback را در زرین‌پال ثبت کنید |
| آپلود تصویر رد می‌شود | `fileinfo`/`gd` نبود یا حجم بیش از حد | افزونه‌ها را فعال کنید؛ حداکثر ۴ مگابایت برای تصویر محصول |
| «تعداد تلاش‌های ورود بیش از حد مجاز» | محدودسازی نرخ | ۵ دقیقه صبر کنید یا فایل‌های `storage/cache/rl_*.json` را حذف کنید |
| تاریخ‌ها چند ساعت اختلاف دارند | `timezone_offset` | پنل → تنظیمات سایت → اختلاف زمانی (تهران = `12600`) |

---

## ۱۰. به‌روزرسانی

1. از پایگاه داده پشتیبان بگیرید (پنل → پشتیبان‌ها) و فایل‌ها را هم کپی کنید.
2. فایل‌های جدید را جایگزین کنید؛ `storage/`, `public/uploads/`, `.env` و `storage/installed.lock` را **نگه دارید**.
3. پنل مدیریت → اطلاعات سیستم: نسخه برنامه و وضعیت افزونه‌ها را بررسی کنید.
4. `php tests/run.php` را اجرا کنید و پنل را مرور کنید.
