# Analisis Migrasi ke PHP 8.3

**Proyek:** SHF OPIS  
**Tanggal Analisis:** 2026-07-02  
**Kondisi Saat Ini:** PHP `^7.2.5` + Laravel `^7.0`  
**Target:** PHP `8.3` + Laravel `10` atau `11`

---

## Ringkasan Eksekutif

Migrasi ini **tidak bisa hanya mengganti versi PHP saja**. Laravel 7 tidak mendukung PHP 8.3. Upgrade harus dilakukan secara bertahap: **Laravel 7 → 8 → 9 → 10 (minimum)**, atau langsung ke Laravel 11. Ini adalah migrasi besar yang menyentuh hampir semua lapisan aplikasi.

---

## 1. Kondisi Saat Ini

| Komponen | Versi Sekarang | Target |
|---|---|---|
| PHP | `^7.2.5` | `8.3.x` |
| Laravel | `^7.0` | `10.x` atau `11.x` |
| PHPUnit | `^8.5` | `^10.0` |
| Total file PHP (app/) | 177 file | — |
| Total file PHP (database/) | 116 file | — |

---

## 2. Apakah Perlu Upgrade Laravel?

**Ya, wajib.** Berikut alasannya:

| Versi Laravel | PHP Minimum | PHP Maksimum |
|---|---|---|
| Laravel 7 | PHP 7.2.5 | PHP 8.0 (tidak resmi) |
| Laravel 8 | PHP 7.3 | PHP 8.1 |
| Laravel 9 | PHP 8.0 | PHP 8.2 |
| Laravel 10 | PHP 8.1 | PHP 8.3 ✅ |
| Laravel 11 | PHP 8.2 | PHP 8.3 ✅ |

Laravel 7 sudah **End of Life** dan tidak mendukung PHP 8.3 secara resmi. Upgrade ke **Laravel 10** adalah pilihan minimum yang aman, dengan Laravel 11 sebagai pilihan modern.

**Rekomendasi:** Laravel 10, karena lebih stabil dan dokumentasi migrasi dari L7→L10 lebih lengkap dibanding langsung ke L11.

---

## 3. Perubahan pada Package / Dependency

### 3.1 Package yang Harus Di-upgrade

| Package | Versi Sekarang | Versi Target | Keterangan |
|---|---|---|---|
| `laravel/framework` | `^7.0` | `^10.0` | Core framework |
| `barryvdh/laravel-dompdf` | `^0.9.0` | `^2.0` atau `^3.0` | Breaking changes di v1→v2 |
| `doctrine/dbal` | `2.*` | `^3.0` | L10 membutuhkan DBAL v3 |
| `guzzlehttp/guzzle` | `^6.3` | `^7.0` | L10 butuh Guzzle 7 |
| `inertiajs/inertia-laravel` | `^0.2.5` | `^1.0` atau `^2.0` | Breaking changes signifikan |
| `laravel/telescope` | `^3.5` | `^4.0` atau `^5.0` | Kompatibilitas L10 |
| `laravel/ui` | `^2.0` | `^4.0` | Kompatibilitas L10 |
| `league/flysystem-sftp` | `~1.0` | `^3.0` | L9+ menggunakan Flysystem 3 |
| `maatwebsite/excel` | `^3.1` | `^3.1` (update patch) | Perlu verifikasi L10 compat |
| `pusher/pusher-php-server` | `~4.0` | `^7.0` | Breaking changes besar |
| `tightenco/ziggy` | `^0.9.4` | `^1.0` atau `^2.0` | Breaking changes di v1 |
| `simplesoftwareio/simple-qrcode` | `^4.2` | `^4.2` atau `^5.0` | Perlu verifikasi |
| `laravel/tinker` | `^2.0` | `^2.8` | Minor update |

### 3.2 Package yang Dihapus (Fungsionalitasnya Sudah Built-in Laravel)

| Package | Status | Pengganti |
|---|---|---|
| `fideloper/proxy: ^4.2` | **HAPUS** | Built-in `TrustProxies` middleware di L8+ |
| `fruitcake/laravel-cors: ^2.0` | **HAPUS** | CORS sudah built-in di L9+ via `config/cors.php` |

### 3.3 Package Dev yang Harus Di-upgrade

| Package | Versi Sekarang | Versi Target | Keterangan |
|---|---|---|---|
| `phpunit/phpunit` | `^8.5` | `^10.0` | Major breaking changes |
| `facade/ignition` | `^2.0` | Ganti ke `spatie/laravel-ignition ^2.0` | Package diganti |
| `fzaninotto/faker` | `^1.9.1` | Ganti ke `fakerphp/faker ^1.9` | Package original abandoned |
| `nunomaduro/collision` | `^4.1` | `^6.0` atau `^7.0` | Kompatibilitas L10 |
| `mockery/mockery` | `^1.3.1` | `^1.6` | Update patch |

---

## 4. Perubahan Kode PHP

### 4.1 Perubahan PHP 8.0 (dari PHP 7.2)

| Perubahan | Dampak | File Terdampak |
|---|---|---|
| **`each()` dihapus** | Wajib ganti dengan `foreach` — **ditemukan di 9 file** | Lihat daftar di bawah |
| `create_function()` dihapus | Ganti dengan `Closure` / anonymous function | Perlu dicek |
| Strict type comparison lebih ketat | `0 == "foo"` sekarang `false` (bukan `true`) | Potensi bug tersembunyi |
| `str_contains()`, `str_starts_with()`, `str_ends_with()` tersedia | Bisa refactor dari `strpos()` | Opsional |

> ⚠️ **TEMUAN KRITIS: Fungsi `each()` Dipakai di 9 File**
> `each()` sudah deprecated di PHP 7.2 dan **dihapus total di PHP 8.0**. Ini adalah blocker utama — aplikasi akan crash tanpa perbaikan ini.
>
> | File | Keterangan |
> |---|---|
> | `app/Models/Memo.php` | Logic memo |
> | `app/Http/Controllers/User/MemoController.php` | Controller terbesar (1.758 baris) |
> | `app/Http/Controllers/User/ApiPaymentCoaController.php` | API payment |
> | `app/Services/Ticketing/SlaService.php` | SLA calculation |
> | `app/Models/Ticketing/TicketHistory.php` | Ticket history |
> | `app/Models/Ticketing/Ticket.php` | Ticket model |
> | `app/Models/D_Memo_Invoices.php` | Invoice model |
> | `app/Models/Ref_Module_Approver.php` | Reference model |
> | `app/Models/RefModuleApproverPayment.php` | Reference model |
>
> **Fix:** Ganti semua `each($arr)` dengan `foreach ($arr as $key => $value)`

### 4.2 Perubahan PHP 8.1

| Perubahan | Dampak | Keterangan |
|---|---|---|
| Native `enum` | Saat ini `TicketStatus`, `TicketPriority`, dll. pakai class constants — masih valid, tidak wajib diubah | Opsional upgrade ke native enum |
| `readonly` property | Fitur baru, tidak breaking | Opsional |
| Intersection types | Fitur baru | Opsional |
| `never` return type | Fitur baru | Opsional |

### 4.3 Perubahan PHP 8.2 (Breaking)

| Perubahan | Dampak | Aksi |
|---|---|---|
| **Dynamic properties deprecated/error** | `$obj->undeclaredProp = val` di class yang bukan `stdClass` akan throw error | Cek semua Model dan class — pastikan semua property dideklarasikan atau gunakan `#[AllowDynamicProperties]` |
| `${var}` string interpolation dihapus | `"Hello ${name}"` tidak valid lagi | Ganti ke `"Hello {$name}"` |
| `utf8_encode()` / `utf8_decode()` deprecated | Ganti ke `mb_convert_encoding()` | Perlu dicek di Helpers dan Mail |

### 4.4 Perubahan PHP 8.3

| Perubahan | Dampak |
|---|---|
| Typed class constants | Fitur baru, tidak breaking |
| `json_validate()` | Fitur baru, tidak breaking |
| `unserialize()` lebih ketat | Perlu audit jika ada usage di session/cache custom |
| Dynamic class constant fetch (`$class::$const`) | Perlu dicek jika ada pattern ini |

---

## 5. Perubahan Laravel per Versi

### 5.1 Laravel 7 → 8 (Breaking Changes)

| Area | Perubahan | Dampak di Proyek Ini |
|---|---|---|
| **Directory seeds** | `database/seeds/` → `database/seeders/` + namespace `Database\Seeders` | **10 seed file** harus pindah + ubah namespace |
| **Factory class-based** | Factory berbasis function → Factory berbasis class | **7 factory file** harus di-rewrite total |
| **Model `$dates`** | `protected $dates` deprecated, ganti ke `$casts` | Perlu audit semua Model |
| **Route caching** | Format route baru | Minor |
| **`Kernel.php` middleware** | Group middleware berubah | Update `Http/Kernel.php` |
| **`with()` di Blade** | Ada perubahan behavior | Perlu dicek |

### 5.2 Laravel 8 → 9 (Breaking Changes)

| Area | Perubahan | Dampak |
|---|---|---|
| **PHP minimum 8.0** | Wajib PHP 8.0+ | Semua kode harus kompatibel PHP 8 |
| **Flysystem 3** | `Storage` facade API berubah | Cek semua usage `Storage::disk('sftp')`, file download |
| **`fruitcake/cors` dihapus** | CORS built-in | Hapus package, konfigurasi via `config/cors.php` |
| **`fideloper/proxy` dihapus** | TrustProxies built-in | Hapus package |
| **`str()` helper** | Fluent string helper | Opsional |

### 5.3 Laravel 9 → 10 (Breaking Changes)

| Area | Perubahan | Dampak |
|---|---|---|
| **PHP minimum 8.1** | Wajib PHP 8.1+ | — |
| **Native type hints** | Method signatures di Laravel core pakai native types | Jika override method framework, signature harus match |
| **`doctrine/dbal` 3** | Migrasi `change()` column menggunakan DBAL 3 | Upgrade `doctrine/dbal` ke `^3.0` |
| **Deprecated helpers dihapus** | Beberapa global helpers L8/L9 yang deprecated dihapus | Perlu audit |

---

## 6. File-file yang Pasti Harus Diubah

### 6.1 Wajib Diubah

| File / Folder | Perubahan |
|---|---|
| `composer.json` | Update semua versi dependency |
| `database/seeds/*.php` → `database/seeders/` | Rename folder + update namespace semua seed (10 file) |
| `database/factories/*.php` | Rewrite total ke class-based factory (7 file) |
| `app/Http/Kernel.php` | Update middleware groups sesuai L10 |
| `app/Providers/AppServiceProvider.php` | Review kompatibilitas Inertia v1 |
| `config/app.php` | Review perubahan config L10 |
| `app/Exceptions/Handler.php` | Signature method berubah di L10 |
| `routes/web.php`, `routes/api.php` | Review jika ada pattern yang deprecated |
| Semua Model (`app/Models/*.php`) | Audit dynamic properties, pastikan `$dates` sudah jadi `$casts` |

### 6.2 Perlu Audit dan Kemungkinan Diubah

| Area | File | Risiko |
|---|---|---|
| Inertia.js API | `app/Providers/AppServiceProvider.php` + semua Controller yang return `Inertia::render()` | **Tinggi** — API v0.2 → v1.0 berbeda |
| SFTP / Storage | `app/Http/Controllers/FileDownloadController.php`, `TicketController.php` | **Sedang** — Flysystem 3 ada breaking changes |
| Mail classes | 9 file di `app/Mail/` | **Rendah** — review constructor signature |
| Notification | `app/Notifications/ApprovalNotification.php`, `TicketNotification.php` | **Rendah** |
| Middleware | `app/Http/Middleware/*.php` (11 file) | **Rendah** — mostly structural |
| Helpers | `app/Helpers/*.php` (5 file) | **Rendah** — review `utf8_encode` usage |
| Jobs | `app/Jobs/ProcessHopesPayment.php` | **Rendah** |
| Exports/Imports | `app/Exports/`, `app/Imports/` | **Rendah** — Excel package update |

---

## 7. Perubahan Frontend (Inertia.js)

Karena proyek menggunakan **InertiaJS**, upgrade dari `^0.2.5` ke `^1.0` juga menyentuh sisi frontend:

| Perubahan | Keterangan |
|---|---|
| `Inertia::share()` API | Berubah cara sharing global data |
| `$page.props` structure | Berubah di Inertia v1 |
| `useForm()` | API baru di Inertia v1 |
| `Link` component | Nama dan props berubah |

Perlu audit file JavaScript/Vue/React yang menggunakan Inertia.

---

## 8. Estimasi Waktu Pengerjaan

### Asumsi: 1-2 Developer, full-time

| Tahap | Aktivitas | Estimasi |
|---|---|---|
| **Persiapan** | Setup environment PHP 8.3, backup, buat branch migrasi | 1-2 hari |
| **Upgrade Laravel Step-by-step** | L7→L8→L9→L10, satu per satu, cek breaking changes per versi | 5-8 hari |
| **Upgrade Packages** | Update composer.json, resolve conflict, test tiap package | 3-5 hari |
| **Refactor Seeds & Factories** | Pindah folder, ubah namespace, rewrite factories (17 file) | 2-3 hari |
| **Fix PHP Compatibility** | Dynamic properties, string interpolation, type hints | 2-3 hari |
| **Upgrade Inertia (PHP + JS)** | Migrasi API Inertia v0.2 → v1 (ini cukup signifikan) | 3-5 hari |
| **Fix Storage/Flysystem** | Update code yang pakai `Storage::disk('sftp')` | 1-2 hari |
| **Testing & Bug Fixing** | Manual testing semua fitur, fix regresi | 5-10 hari |
| **QA & Staging Deploy** | Deploy ke staging, UAT, fix temuan | 3-5 hari |
| **Buffer** | Hal tak terduga (package yang tidak kompatibel, dll.) | 3-5 hari |

### **Total Estimasi: 4 – 8 Minggu**

| Skenario | Waktu |
|---|---|
| **Optimis** (1-2 developer, no major blocker) | **4 minggu** |
| **Realistis** (ada beberapa blocker, package incompatible) | **6 minggu** |
| **Pesimis** (banyak kode legacy, kurang test coverage) | **8 minggu** |

---

## 9. Risiko Utama

| Risiko | Level | Mitigasi |
|---|---|---|
| **`each()` dipakai di 9 file** — dihapus di PHP 8.0, app akan crash | 🔴 Kritis | Fix dulu sebelum apapun, ganti dengan `foreach` |
| `reinink/remember-query-strings ^0.1.0` kemungkinan **abandoned** / tidak ada L10 support | 🔴 Tinggi | Cek GitHub, kemungkinan perlu implementasi manual |
| Inertia upgrade dari v0.2 ke v1 = **rewrite signifikan** di JS side | 🔴 Tinggi | Audit semua Vue/React component sebelum mulai |
| `MemoController.php` berukuran **1.758 baris** — sulit di-debug saat migrasi | 🔴 Tinggi | Pertimbangkan refactor sebelum migrasi atau jadikan prioritas testing |
| Tidak ada automated test coverage → regresi sulit terdeteksi | 🔴 Tinggi | Tambah test coverage minimal sebelum/selama migrasi |
| Integrasi HOPES Payment API (external) — perlu verifikasi ulang setelah upgrade | 🟡 Sedang | Test di staging dengan dummy payment sebelum go-live |
| `fzaninotto/faker` abandoned, data seeder mungkin perlu disesuaikan | 🟡 Sedang | Ganti ke `fakerphp/faker` dan review method yang deprecated |
| Flysystem 3 API berubah (SFTP) → file download bisa error | 🟡 Sedang | Test semua fitur download/upload file secara menyeluruh |
| PHP strict type comparison bisa munculkan bug tersembunyi | 🟡 Sedang | Testing menyeluruh, terutama fitur approval dan status flow |

---

## 10. Langkah yang Disarankan

### Urutan Pengerjaan yang Direkomendasikan

```
1. Buat branch baru: feature/php83-migration
2. Setup Docker/Laragon dengan PHP 8.3
3. Upgrade Laravel secara bertahap:
   composer require laravel/framework:^8.0 (fix semua breaking changes)
   composer require laravel/framework:^9.0 (fix semua breaking changes)
   composer require laravel/framework:^10.0 (fix semua breaking changes)
4. Update semua package satu per satu
5. Fix PHP 8.x breaking changes
6. Upgrade Inertia (PHP + JS)
7. Testing menyeluruh per fitur
8. Deploy ke staging → UAT
```

### Hal yang TIDAK Perlu Diubah

- **Logic bisnis**: Semua logic approval, memo, ticketing tidak perlu diubah
- **Database migrations**: Tidak perlu diubah (hanya struktur file seeder yang berubah)
- **Enums** (`TicketStatus`, `TicketPriority`, dll.): Class-based constants tetap valid di PHP 8.3, tidak wajib dikonversi ke native `enum`
- **API endpoints**: Tidak perlu berubah
- **Frontend logic** (selain bagian Inertia API)

---

## 11. Kesimpulan

| Pertanyaan | Jawaban |
|---|---|
| Apakah perlu upgrade Laravel? | **Ya, wajib.** Laravel 7 tidak support PHP 8.3 |
| Laravel versi berapa yang disarankan? | **Laravel 10** (stabil, support PHP 8.3, LTS hingga Agustus 2026) |
| Berapa banyak file yang berubah? | **~40-60 file** yang pasti berubah, ~100 file yang perlu diaudit |
| Estimasi waktu total? | **4-8 minggu** (realistis ~6 minggu) |
| Risiko terbesar? | Inertia upgrade (JS side) + tidak ada automated tests |
| Perlu rewrite total? | **Tidak.** Ini adalah upgrade/migration, bukan rewrite |
