WISECP sunucu modülü, ödenmiş bir siparişi hosting panelinde ya da bulut sağlayıcısında gerçek bir hesaba dönüştüren Servers tipi modüldür. Sınıfınız ServerModule taban sınıfını genişletir ve create(), suspend(), unsuspend(), cancel() gibi yaşam döngüsü metotlarını yazarsınız; çekirdek bu metotları adıyla çağırır ve döndürdüğünüz değeri hizmetin seçeneklerine yazar.

Bu rehberde resmî geliştirici belgelerine dayanarak sunucu modülünün dizin yapısını, config.php alanlarını, belgelerdeki zorunlu ve isteğe bağlı metotları, sağlama yaşam döngüsünü, create() dönüş biçimini ve modülü test etme sırasını anlatıyoruz. Modül sistemine yeniyseniz önce WISECP modül geliştirme rehberi yazısını okuyun; hazır bulut entegrasyonlarını kullanmak istiyorsanız WISECP bulut modülleri yazısı daha uygun olabilir.

Çekirdek sunucu modülünüzü nasıl çağırır

Çekirdek sunucu modülünüzü nasıl çağırır: Services::run_module(), Services::instance_module(), Modules::getInstance(), ModuleQueue

Servers, belgelere göre en büyük modül tipidir: 50 modül, bunların üçü paylaşımlı hosting, özel makine ve sanallaştırma için kum havuzu örneğidir. Çekirdek sınıfınızı hiç new ile kurmaz; örneği fabrikadan çözer ve fiili adıyla çağırır. Yazmadığınız bir fiil atlanır. Akışın parçaları:

  • Services::run_module(): Tek kapı. Örneği kurar, takma adları çözer, metodu çalıştırır, sonucu uygular.
  • Services::instance_module(): Modül tipini hizmetten seçer, fabrikayı çağırıp hizmeti ve siparişi doldurur; hosting ve server tipleri Servers'a gider.
  • Modules::getInstance(): Kanonik fabrika: yapılandırma, dil, örnek önbelleği.
  • ModuleQueue: Yeniden deneyen arka plan işçisi; aynı kapıyı kullanır, sonra aksiyonun gerektirdiği durumu uygular.
php
Services::run_module($id, 'create');                       // argüman yok
Services::run_module($id, 'change_password', [$password]); // tek konumsal dize
Services::run_module($service, 'upgrade', [$newProduct]);  // yeni ürün dizisi

Dizin yapısı ve sınıf iskeleti

Her modül için, içindeki sınıfla birebir aynı adı taşıyan tek bir dizin oluşturursunuz:

bash
coremio/modules/Servers/Acme/
    Acme.php         sınıf: extends ServerModule
    ApiClient.php    kendi HTTP sarmalayıcınız, düz new, WISECP modülü değil
    config.php       künye, sunucu form alanları, desteklenen kartlar ve araçlar
    logo.png         modül seçicide görünür
    lang/en.php      $this->lang, dil başına bir dosya
    pages/           get_page() ile render edilen isteğe bağlı şablonlar
php
namespace WISECP\Modules\Servers;

use Exception;
use Language;
use ServerModule;

class Acme extends ServerModule
{
    private ApiClient $api;

    // set_server() tarafından çağrılır; onu hem yapıcı hem set_service() koşar,
    // $this->server dolduktan ve sırları çözüldükten sonra.
    protected function define_server_info(array $server = []): void
    {
        include_once __DIR__ . DS . 'ApiClient.php';
        $this->api = new ApiClient($server);
    }
}

ApiClient sizin yazacağınız düz bir PHP sınıfıdır; modül değildir ve otomatik yüklenmediği için include_once ile dahil edilir. Taban sınıf $server['password'] değerini tek bir noktada çözdüğünden define_server_info() metoduna parola her zaman düz metin olarak ulaşır; yeniden çözmeye çalışmayın.

config.php: sunucu formu ve bağlantı alanları

Sunucu kaydı ekranında hangi alanların görüneceğine config.php karar verir. Belgelerdeki örnek:

php
return [
    'name'                => 'Acme Cloud',

    // 'hosting' = alan adı tabanlı hesaplar, 'server' = VPS ya da özel makineler.
    'type'                => 'hosting',

    // Uzun API jetonu parola alanına değil erişim anahtarı alanına yazılır.
    'use-access-hash'     => true,
    'require-access-hash' => true,

    'use-test-connection' => true,
    'use-port'            => true,
    'not-secure-port'     => 2082,
    'secure-port'         => 2083,

    // Ek alanlar $server['fields'] içine düşer. 'crypt' değeri şifreli saklar.
    'fields' => [
        'region'    => ['type' => 'text', 'name' => '{lang.region}', 'col_class' => 'col-md-6'],
        'sub_token' => ['type' => 'password', 'name' => '{lang.sub_token}', 'crypt' => true],
    ],

    // Hesabı sağlayıcı tarafında hangi hizmet seçeneğinin tanımladığı.
    'service-relationship' => 'domain',
];

Belgelerin notu önemlidir: servers.password kolonu bir varchar'dır ve şifrelenmiş uzun bir jeton oraya sığmaz; bu yüzden uzun API jetonları için use-access-hash açılır. {lang.region} gibi yer tutucular modülün dil dosyasına karşı çözülür.

Katmanları bu sırayla yazın

Katmanları bu sırayla yazın: define_server_info(), ardından test_connect(), product_configuration() ve save_product_configuration(), artı plan listesini..., create(), sonra...

Belgeler yaşam döngüsüyle başlamanın boşa iş olduğunu söyler, çünkü create() alıcının seçimlerini hizmet seçeneklerinden okur ve o seçenekler ancak ürün formu tanımlıysa oluşur. Önerilen sıra:

  • define_server_info(), ardından test_connect(): sunucuyu ekleyin, kimlik bilgilerini kanıtlayın.
  • product_configuration() ve save_product_configuration(), artı plan listesini dolduran çağrılabilir metot.
  • create(), sonra suspend(), unsuspend(), cancel().
  • change_password() ve upgrade().
  • list(), dashboard_data(), tek oturum açma metotları, metrikler.
  • configure_features() ve araçlar.

Yaşam döngüsü metotları: zorunlu ve isteğe bağlı

Bu metotların hiçbiri taban sınıfta soyut bildirilmez; çekirdek her birini method_exists() ile yoklar. Belgelerdeki tablo:

MetotZorunluNe zaman çağrılırSonraki durum
define_server_infoevetHer örneklemeyok
test_connectevetSunucu formunda Bağlantıyı Test Etyok
product_configurationevetÜrün detayı, Modül sekmesiyok
createevetSipariş onaylandığında ya da adminde Yeniden Oluşturactive
suspendevetVadesi geçen fatura ya da elle askıya almasuspended
unsuspendevetÖdeme alındığında ya da elle geri açmaactive
cancelevetİptal işlendiğindecancelled
change_passwordevetMüşteri ya da yönetici parolayı değiştirdiğindedeğişmez
upgradeevetAynı modülde kalan plan değişikliğindedeğişmez
renewisteğe bağlıYenileme faturası ödendiğindedeğişmez
change_limits, reset_limitsisteğe bağlıSağlayıcı hesap başına limit ezmeye izin veriyorsadeğişmez
addon_*isteğe bağlıHizmetteki bir eklenti durum değiştirdiğindeyalnız eklenti
lististeğe bağlıYönetici Hesapları İçe Aktar ekranını açtığındayok
php
protected function define_server_info(array $server = []): void;
public function test_connect(): array|bool;
public function product_configuration(array $data = []): array;
public function save_product_configuration(array &$values): void;
public function create(): array|bool;
public function suspend(): bool;
public function unsuspend(): bool;
public function cancel(): bool;
public function renew(): bool;
public function upgrade(array $new_product = []): bool;
public function change_password(string $password): bool;

Ürün formunda yöneticinin seçtiği değerler sağlama kodunuza $this->options['creation_info'] içinde ulaşır. Belgeler, seçenek değeri olarak sağlayıcının sayısal kimliğini değil planın adını saklamanızı söyler: yük dengeli bir sunucu grubunda aynı plan farklı makinelerde farklı kimlik taşıyabilir, ad ise sabittir. Kimliğe create() içinde çevirin. Ürün tarafı için WISECP ürün oluşturma rehberine bakın.

create() ne döndürmeli

Sade bir başarı için true, aksi hâlde bir dizi döndürün. Dizinin ayrılmış anahtarları hizmet seçeneklerine özyinelemeli olarak birleştirilir:

AnahtarNereye yazılırNe için
configSeçeneklerde config altınaHesap kimliği: user, şifrelenmiş password, home_dir, sağlayıcı kimliği
loginlogin altınaMüşteri panelinin gösterdiği veya tek oturum açmanın kullandığı bilgiler
creation_infocreation_info altınaGerçekte neyin sağlandığını kaydetmek
optionsSeçenek köküneDiğer anahtarların kapsamadığı her şey
statusSaklanmaz, kuyruk tüketirinprocess ya da waiting: eşzamansız sağlama bitene kadar hizmeti aktif yapmaz
diğer anahtarlarSeçenek köküne olduğu gibihostname, ip, ftp_info gibi değerler

Belgelerdeki create() örneğinin kısaltılmış hâli; $this->api sizin istemcinizdir:

php
public function create(): array|bool
{
    $domain = $this->options['domain'] ?? '';
    if (!$domain) throw new Exception($this->lang['error-domain-required']);

    // Yeniden sağlama: önceki koşudaki kimliği yeniden kullanın.
    $username = $this->options['config']['user'] ?? '';
    if (!$username) $username = self::username_generator($domain);

    $password = ($this->options['config']['password'] ?? '') !== ''
        ? $this->decode_str($this->options['config']['password'])
        : Utility::generate_hash(12);

    $creation = $this->options['creation_info'] ?? [];

    $parameters = [
        'username'  => $username,
        'password'  => $password,
        'domain'    => $domain,
        'plan_id'   => $this->resolve_plan_id($creation['plan'] ?? ''),
        'disk'      => $this->get_limit('disk_limit'),
        'bandwidth' => $this->get_limit('bandwidth_limit'),
    ];

    // Yeniden deneme güvenliği: kuyruk bu metodu hatadan sonra tekrar koşar.
    if (!$this->api->account_exists($username))
        $this->api->call('accounts', $parameters, 'POST');

    return [
        'config' => [
            'user'     => $username,
            'password' => $this->encode_str($password),
            'home_dir' => '/home/' . $username,
        ],
        'ip' => $this->server['ip'] ?? '',
    ];
}

suspend(), unsuspend() ve cancel() aynı kalıbı izler: hesap kimliğini $this->options['config']['user'] içinden okur, sağlayıcıyı çağırır ve bool döndürür. Sağlayıcı hata verirse false döndürmek yerine çevrilmiş bir mesajla Exception fırlatın.

Metodunuz çalışmadan önce elinizde hazır duranlar

Metodunuz çalışmadan önce elinizde hazır duranlar: $this->server, $this->service, $this->product, $this->user, $this->order, $this->options ve save_options(), get_limit()

Yapıcı ve set_service() aşağıdakileri zaten doldurur; bunlar için sorgu atmayın:

  • $this->server: ip, hostname, kullanıcı adı, çözülmüş parola, erişim anahtarı ve config.php'deki fields.
  • $this->service, $this->product, $this->user, $this->order: Hizmet, ürün, müşteri ve kaynak sipariş, düz dizi olarak.
  • $this->options ve save_options(): Hizmet seçenekleri; metot ortasında kalıcılaştırmak için save_options() çağırın.
  • get_limit(): Çözümlenmiş limit; anahtarlar disk_limit, bandwidth_limit, email_limit, database_limit, addons_limit, subdomain_limit, ftp_limit, park_limit, max_email_per_hour.
  • $this->addon_params ve $this->requirement_params: Eklenti toplamları ve sipariş formu cevapları.
  • encode_str(), decode_str(): Sırrı seçeneklere yazmadan önce şifreleyin, sağlayıcıya göndermeden önce çözün.

Modül aksiyonlarının etrafındaki kancalar

Sağlama akışına başka bir modülden veya kendi kanca dosyanızdan müdahale etmek için belgeler üç kanca listeler. Ayrıntılı kullanım için WISECP kanca kullanımı yazısına bakın.

  • gate:service.module_action: Metodunuzdan önce çalışır; boş olmayan bir dize döndüren dinleyici aksiyonu veto eder.
  • filter:service.module_result: Sonuç uygulanmadan önce referansla çalışır; saklanacak değeri yeniden yazabilir.
  • action:service.module_ran: Sonuç uygulandıktan sonra hizmet, örnek, aksiyon, sonuç ve hata ile çalışır.

Modülü test etme

Belgelerin ön koşulları test sırasını da belirler: API erişimi olan bir sağlayıcı hesabı, bağlantı testini geçen bir sunucu kaydı ve o sunucuya bağlı bir test ürünü. Önerilen akış:

  • Modül dizinini geliştirme kurulumuna kopyalayın; bozabileceğiniz bir kurulumda çalışın.
  • Panelde yeni bir sunucu kaydı ekleyip modülünüzü seçin ve Bağlantıyı Test Et ile test_connect() metodunu doğrulayın. Panel tarafındaki akış için WISECP sunucu ekleme yazısına bakın.
  • Sunucuya bağlı bir test ürünü oluşturup Modül sekmesinde product_configuration() alanlarının geldiğini ve kaydedildiğini kontrol edin.
  • Test siparişini onaylayıp create() çalıştırın; hizmet seçeneklerinde config anahtarlarının oluştuğunu doğrulayın.
  • Askıya alma, geri açma, parola değiştirme ve iptal aksiyonlarını yönetici panelinden tek tek tetikleyin ve sağlayıcı tarafındaki sonucu kontrol edin.
  • Her sağlayıcı çağrısını save_log() ile kaydedin; böylece hata veren çağrı panelin işlem geçmişinden teşhis edilebilir.

Dönüş değerlerinin kuyruğa etkisini bilmek de testte işinizi kolaylaştırır: metot yoksa run_module null döner ve kuyruk "modül metodu bulunamadı" kaydı düşer; false dönerse modül reddetmiş sayılır, kuyruk öğeyi başarısız işaretler ve yeniden dener. Anahtar ve onay alanları "0" ve "1" dizelerini gönderdiği için değerleri empty() ile değil (int) ($data['key'] ?? 0) === 1 ile sınayın.

Sık Sorulan Sorular

ServerModule'de zorunlu metotlar hangileri?

Belgelerdeki tabloya göre define_server_info, test_connect, product_configuration, create, suspend, unsuspend, cancel, change_password ve upgrade zorunlu; renew, limit, eklenti, list ve metrik metotları isteğe bağlıdır.

Hizmeti silme işlemi için terminate() yazmalı mıyım?

Gerekmez. cancel() yazmanız yeterlidir; terminate() yoksa çekirdek cancel() metodunu dener.

Müşteri panelinde dosya yöneticisi gibi araçları nasıl eklerim?

Araçlar tool_data() ve tool_action() metotlarıyla eklenir; ServerModule araç kataloğunu taşır ve hepsi kapalı gelir. Araçlar ancak create() hesap kimliğini sakladıktan sonra açılır.

cPanel veya Plesk için hazır modül var mı?

Servers tipinde 50 modül bulunur ve belgelerdeki örneklerde cPanel modülü geçer. Panellerin kendisi hakkında bilgi için cPanel nedir ve Plesk nedir yazılarına bakabilirsiniz.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: WISECP nedir · WISECP modül geliştirme · WISECP kanca kullanımı · WISECP sunucu ekleme · WISECP bulut modülleri · WISECP ürün oluşturma · VPS nedir