# Onoxsoft Plugin SDK — Başlangıç Kılavuzu

## 1. Giriş

Onoxsoft Plugin SDK, hosting kontrol paneline özel işlevsellik eklemenizi sağlar. Bir plugin:

- Panel event'lerine hook ekleyebilir (DNS oluşturma, hesap suspend, vb.)
- Admin ve müşteri sidebar'ına öğe ekleyebilir
- Kendi HTTP route'larını tanımlayabilir
- Ayarlar formu (settings_schema) ile yönetilebilir yapılandırma sunar

---

## 2. Plugin Yapısı

```
my-plugin/
├── plugin.json          ← Zorunlu manifest
├── icon.svg             ← İsteğe bağlı ikon (48×48 önerilir)
├── handlers/
│   ├── OnDomainCreated.php
│   └── MyController.php
├── screenshots/
│   └── main.png
└── README.md
```

Tüm bu dosyalar tek bir `.zip` arşivine sıkıştırılır ve marketplace'e yüklenir ya da panel admin UI'den yüklenir.

---

## 3. Manifest (plugin.json) — Hızlı Başlangıç

```json
{
    "slug": "benim-pluginim",
    "name": "Benim Pluginim",
    "version": "1.0.0",
    "description_tr": "Bu plugin örnek bir işlev sunar",
    "author": { "name": "Ad Soyad", "email": "email@example.com" },
    "minimum_panel_version": "0.18.0",
    "category": "integration",
    "permissions": ["http:outbound"],
    "hooks": {},
    "routes": [],
    "settings_schema": {},
    "sidebar_items": { "admin": [], "customer": [] }
}
```

Tam şema ve alan açıklamaları için `MANIFEST.md` dosyasına bakın.

---

## 4. Hook Ekleme

Hook'lar, panel olaylarına tepki veren PHP sınıflarıdır.

### Örnek: Domain oluşturulduğunda bildirim gönder

`plugin.json` içinde:
```json
"hooks": {
    "domain.created": "handlers/OnDomainCreated.php"
}
```

`handlers/OnDomainCreated.php`:
```php
<?php

namespace OnoxPlugins\BenimPluginim;

class OnDomainCreated
{
    public function handle($payload): mixed
    {
        $domain = $payload['domain'] ?? 'bilinmiyor';

        // Örnek: bir webhook'a bildirim gönder
        \Http::post('https://example.com/webhook', [
            'event'  => 'domain.created',
            'domain' => $domain,
        ]);

        return $payload; // payload'ı değiştirip döndürebilirsiniz
    }
}
```

> **Not:** Handler dosyasındaki sınıf adı `OnoxPlugins\{StudlyCaseSlug}\{ClassName}` namespace'inde olmalıdır.

### Mevcut Hook Olayları

| Olay | Payload |
|------|---------|
| `domain.created` | `['domain' => '...', 'account_id' => ...]` |
| `domain.deleted` | `['domain' => '...']` |
| `account.suspended` | `['account_id' => ...]` |
| `account.unsuspended` | `['account_id' => ...]` |
| `dns.record.created` | `['zone' => '...', 'type' => '...', 'value' => '...']` |
| `dns.record.updated` | `['zone' => '...', 'record_id' => ...]` |
| `dns.record.deleted` | `['zone' => '...', 'record_id' => ...]` |
| `backup.completed` | `['account_id' => ..., 'path' => '...']` |
| `ssl.issued` | `['domain' => '...', 'expires_at' => '...']` |

---

## 5. HTTP Route Tanımlama

`plugin.json` içinde:
```json
"routes": [
    { "method": "GET",  "path": "/status",  "handler": "StatusController@index" },
    { "method": "POST", "path": "/action",  "handler": "StatusController@run" }
]
```

Route'lar otomatik olarak `/plugins/{slug}{path}` şeklinde mount edilir.
Örnek: `GET /plugins/benim-pluginim/status`

`handlers/StatusController.php`:
```php
<?php

namespace OnoxPlugins\BenimPluginim;

use Illuminate\Http\Request;

class StatusController
{
    public function index(Request $request): \Illuminate\Http\JsonResponse
    {
        // Plugin izinlerini kontrol et
        $permissions = $request->attributes->get('plugin_permissions', []);

        return response()->json([
            'status'      => 'ok',
            'permissions' => $permissions,
        ]);
    }

    public function run(Request $request): \Illuminate\Http\JsonResponse
    {
        $validated = $request->validate([
            'target' => 'required|string',
        ]);

        // İşlemi yap...

        return response()->json(['message' => 'İşlem başarılı']);
    }
}
```

Tüm plugin route'larına `auth` ve `plugin.sandbox` middleware otomatik uygulanır.
Rate limit: dakikada 60 istek (IP başına, plugin başına).

---

## 6. Sidebar Öğesi Ekleme

```json
"sidebar_items": {
    "customer": [
        {
            "label": "Benim Pluginim",
            "icon": "CubeIcon",
            "route": "/panel/plugins/benim-pluginim"
        }
    ],
    "admin": [
        {
            "label": "Plugin Yönetimi",
            "icon": "PuzzlePieceIcon",
            "route": "/admin/plugins/benim-pluginim"
        }
    ]
}
```

`icon` değeri Heroicons 24/outline ikon adı olmalıdır.

---

## 7. Settings Schema → UI Eşlemesi

Panel, `settings_schema` alanını otomatik olarak bir form UI'ye dönüştürür.

```json
"settings_schema": {
    "api_key": {
        "label": "API Anahtarı",
        "type": "password",
        "required": true,
        "description": "Servis sağlayıcıdan alınan gizli anahtar"
    },
    "webhook_url": {
        "label": "Webhook URL",
        "type": "string",
        "required": false,
        "placeholder": "https://example.com/hook"
    },
    "notify_on_error": {
        "label": "Hata Bildirimlerini Etkinleştir",
        "type": "boolean",
        "default": true
    },
    "max_retries": {
        "label": "Maksimum Deneme Sayısı",
        "type": "number",
        "default": 3
    },
    "log_level": {
        "label": "Log Seviyesi",
        "type": "select",
        "options": ["debug", "info", "warning", "error"],
        "default": "info"
    }
}
```

Kaydedilen ayarlar `installed_plugins.config` JSON sütununda saklanır.
Handler içinden: `PluginRegistry::updateConfig($slug, $settings)` ile okuyabilirsiniz.

---

## 8. Yerel Geliştirme Ortamı

1. Plugin klasörünüzü oluşturun:
   ```bash
   mkdir storage/app/plugins/benim-pluginim
   ```

2. `plugin.json` ve handler dosyalarınızı buraya yerleştirin.

3. Veritabanına manuel kayıt ekleyin:
   ```php
   // tinker ile:
   use App\Domain\PluginSdk\Services\PluginRegistry;
   PluginRegistry::register('benim-pluginim', json_decode(file_get_contents(
       storage_path('app/plugins/benim-pluginim/plugin.json')
   ), true));
   ```

4. Panel'i yeniden başlatın — `PluginLoader::loadAll()` boot sırasında route'ları ve hook'ları kayıt eder.

5. Geliştirme sırasında `.env` dosyasına ekleyin:
   ```
   PLUGIN_MARKETPLACE_ENABLED=false
   ```

---

## 9. Marketplace'e Yayınlama

1. Plugin klasörünüzü `.zip` olarak arşivleyin (kök dizin `plugin.json` içermelidir).
2. [https://marketplace.onox.com.tr](https://marketplace.onox.com.tr) adresinde hesap açın.
3. "Plugin Yükle" bölümünden zip'i yükleyin.
4. İnceleme sürecini (2-5 iş günü) bekleyin.
5. Onaylandıktan sonra plugin tüm Onoxsoft kurulumlarında görünür hale gelir.

### Yayın Kontrol Listesi

- [ ] `plugin.json` tüm zorunlu alanları içeriyor
- [ ] Slug benzersiz ve uygun formatta
- [ ] Tüm tanımlanan `permissions` gerçekten kullanılıyor
- [ ] `minimum_panel_version` doğru belirtilmiş
- [ ] README.md var ve Türkçe açıklama içeriyor
- [ ] Ekran görüntüleri eklenmiş (en az 1)
- [ ] Handler dosyaları doğru namespace kullanıyor (`OnoxPlugins\{StudlyCaseSlug}`)
- [ ] Hassas veri loglanmıyor

---

## 10. Güvenlik Notları (Phase 4)

- Plugin PHP dosyaları doğrudan `require_once` ile yüklenir. Phase 4.5'te izole edilmiş bir sandbox eklenecektir.
- `permissions` listesi sandbox'a rehberlik eder; izin verilmemiş API'lere erişim Phase 4.5'te engellenir.
- Şimdilik: sadece güvendiğiniz kaynaklardan plugin yükleyin.
- Plugin route'larına rate limit uygulanır (60 istek/dakika/IP).
- Tüm plugin indirmeleri HTTPS üzerinden yapılır.
