# Panduan Mengatasi Error Forbidden di Shared Hosting cPanel

## Masalah
Error "403 Forbidden" saat menyimpan data (upload gambar/map) di shared hosting cPanel meskipun folder `storage` sudah memiliki permission 0777.

## Penyebab Umum
1. **Symbolic link belum dibuat** dari `public/storage` ke `storage/app/public`
2. **ModSecurity** memblokir POST data base64 yang besar
3. **File .htaccess** di public/storage memblokir akses
4. **Folder sp-sipt/maps** belum dibuat
5. **PHP functions** seperti `file_put_contents` diblokir oleh hosting provider

## Solusi Step-by-Step

### 1. Buat Symbolic Link (Penting!)

#### Cara A: Via Terminal/SSH (Recommended)
```bash
cd /home/username/public_html
php artisan storage:link
```

#### Cara B: Manual via File Manager cPanel
1. Buka **File Manager** di cPanel
2. Navigasi ke folder `public_html/public`
3. Buat folder baru bernama `storage` (jika belum ada)
4. **Atau gunakan Symlink Manager** di cPanel:
   - Buka **Symlink Manager** atau **File Manager > New Symbolic Link**
   - Source: `/home/username/public_html/storage/app/public`
   - Destination: `/home/username/public_html/public/storage`

### 2. Set Permission Folder yang Benar

Via File Manager cPanel, set permission untuk folder berikut:

```
storage/                    -> 755
storage/app/                -> 755
storage/app/public/         -> 755
storage/app/public/sp-sipt/ -> 755
storage/app/public/sp-sipt/maps/     -> 755
storage/app/public/sp-sipt/documents/-> 755
storage/logs/               -> 755
storage/framework/          -> 755
storage/framework/cache/    -> 755
storage/framework/sessions/ -> 755
storage/framework/views/    -> 755

public/storage/             -> 755 (symbolic link)
```

**Catatan:** Jangan gunakan 0777 di shared hosting karena berbahaya! Gunakan 755.

### 3. Buat Folder yang Diperlukan

Via File Manager atau SSH, buat folder berikut jika belum ada:

```bash
mkdir -p storage/app/public/sp-sipt/maps
mkdir -p storage/app/public/sp-sipt/documents
chmod 755 storage/app/public/sp-sipt
chmod 755 storage/app/public/sp-sipt/maps
chmod 755 storage/app/public/sp-sipt/documents
```

### 4. Cek File .htaccess di public/storage

Pastikan file `public/storage/.htaccess` berisi:

```apache
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule ^(.*)$ public/$1 [L]
</IfModule>

# Allow image files
<FilesMatch "\.(jpg|jpeg|png|gif|svg|webp|pdf|doc|docx)$">
    Allow from all
</FilesMatch>
```

### 5. Nonaktifkan ModSecurity untuk Route Tertentu (Optional)

Jika hosting memblokir POST data besar, tambahkan di `.htaccess` root:

```apache
<IfModule mod_security.c>
    # Disable for specific routes
    SecRuleEngine Off
</IfModule>

# Atau untuk path tertentu saja
<LocationMatch "^/sp-sipt/(store|update)">
    SecRuleEngine Off
</LocationMatch>
```

**Atau** tambahkan di file `.htaccess` di folder `public/`:

```apache
# Increase limits for large uploads
php_value upload_max_filesize 50M
php_value post_max_size 50M
php_value max_execution_time 300
php_value max_input_time 300
php_value memory_limit 256M

# Allow base64 encoded data
<IfModule mod_security.c>
    SecFilterEngine Off
    SecFilterScanPOST Off
</IfModule>
```

### 6. Verifikasi Konfigurasi Laravel

Pastikan file `config/filesystems.php` sudah benar:

```php
'disks' => [
    'public' => [
        'driver' => 'local',
        'root' => storage_path('app/public'),
        'url' => env('APP_URL').'/storage',
        'visibility' => 'public',
    ],
],
```

Dan di `.env`:

```env
APP_URL=https://yourdomain.com
FILESYSTEM_DISK=public
```

### 7. Test Upload Manual

Buat file test di root project: `test-upload.php`

```php
<?php
// Test manual upload
$testData = "Test data " . date('Y-m-d H:i:s');
$path = __DIR__ . '/storage/app/public/sp-sipt/maps/test.txt';

// Create directory if not exists
$dir = dirname($path);
if (!file_exists($dir)) {
    mkdir($dir, 0755, true);
}

// Try to write
if (file_put_contents($path, $testData) !== false) {
    echo "✅ SUCCESS! File written to: " . $path;
    echo "<br>File size: " . filesize($path) . " bytes";
    echo "<br>File contents: " . file_get_contents($path);
} else {
    echo "❌ FAILED! Cannot write to: " . $path;
    echo "<br>Check permissions!";
}

// Check if directory is writable
echo "<br><br>Directory writable: " . (is_writable($dir) ? 'YES ✅' : 'NO ❌');
echo "<br>Directory exists: " . (file_exists($dir) ? 'YES ✅' : 'NO ❌');
echo "<br>Directory permissions: " . substr(sprintf('%o', fileperms($dir)), -4);
?>
```

Akses: `https://yourdomain.com/test-upload.php`

### 8. Alternatif: Ubah Disk Storage

Jika `public` disk tetap bermasalah, gunakan disk `local` dan akses file via controller:

Di `config/filesystems.php`:
```php
'disks' => [
    'sp-sipt' => [
        'driver' => 'local',
        'root' => storage_path('app/sp-sipt'),
    ],
],
```

Lalu ubah di controller:
```php
Storage::disk('sp-sipt')->put($path, $imageData);
```

### 9. Hubungi Provider Hosting

Jika semua cara di atas gagal, kemungkinan hosting provider memblokir fungsi PHP tertentu. Hubungi support dan minta:

1. Aktifkan fungsi `file_put_contents`, `mkdir`, `chmod`
2. Nonaktifkan ModSecurity untuk domain Anda
3. Naikkan limit `post_max_size` dan `upload_max_filesize`
4. Whitelist IP server untuk bypass firewall

## Troubleshooting

### Cek Error Log
```bash
# Via SSH
tail -f storage/logs/laravel.log

# Via cPanel
File Manager > storage/logs/laravel.log
```

### Cek PHP Error Log
```bash
# Via cPanel
File Manager > public_html/error_log
```

### Debug Mode
Aktifkan debug mode di `.env`:
```env
APP_DEBUG=true
LOG_LEVEL=debug
```

**PENTING:** Matikan setelah selesai debugging!

## Kode yang Sudah Diperbaiki

Controller sudah diupdate dengan:
1. ✅ Error handling yang lebih baik
2. ✅ Fallback menggunakan `file_put_contents` langsung
3. ✅ Auto-create directory jika belum ada
4. ✅ Logging error untuk debugging
5. ✅ Graceful failure (tidak crash jika upload gagal)

## Checklist Final

- [ ] Symbolic link `public/storage` sudah dibuat
- [ ] Permission folder storage sudah 755
- [ ] Folder `sp-sipt/maps` sudah dibuat
- [ ] File `.htaccess` sudah dikonfigurasi
- [ ] Test upload manual berhasil
- [ ] Error log tidak menunjukkan error
- [ ] ModSecurity sudah dinonaktifkan (jika perlu)
- [ ] PHP limits sudah dinaikkan

## Kontak Support

Jika masih error setelah mengikuti semua langkah:
1. Screenshot error message
2. Copy isi file `storage/logs/laravel.log`
3. Screenshot permission folder via File Manager
4. Hubungi support hosting dengan informasi di atas

---

**Good Luck!** 🚀
