WISECP'de modül, coremio/modules/{Type}/{Name}/ altında duran ve adı içindeki sınıf dosyasıyla birebir eşleşen bir dizindir. Bir manifest, kayıt yordamı veya kurulum komutu yoktur: doğru adlandırılmış dizin diske kopyalandığı anda platform onu bir sonraki istekte listeler. Üst dizin modülün tipidir ve çekirdeğin hangi metotları çağıracağına, panelde nerede listeleneceğine ve hangi taban sınıfın genişletileceğine tip karar verir.

Bu rehberde resmî geliştirici belgelerine dayanarak 16 modül tipini, dizin düzenini, sınıf adı çözümlemesini, config.php ve dil dosyalarını, yaşam döngüsünü, Modules::getInstance fabrikasını ve WISECP'nin altın kuralı olan "fork etme, genişlet" ilkesini anlatıyoruz. Platformun genel tanıtımı için WISECP nedir yazısına, belirli tiplere geçmek için sunucu modülü ve ödeme geçidi modülü rehberlerine bakabilirsiniz.

16 modül tipi ve taban sınıfları

16 modül tipi ve taban sınıfları: Servers, Payment, Registrars, Product

Belgelere göre on altı tipin sekizinde genişletilecek bir taban sınıf vardır. Kalan sekizi düz sınıflardır; sözleşmeleri, çekirdeğin method_exists ile aradığı metot kümesinden ibarettir. Tip adı büyük küçük harfiyle birlikte her kayıt defteri çağrısına dize olarak geçer; yazım hatası hata değil, sessiz bir boş sonuç üretir.

TipTaban sınıfÇekirdeğin ne için çağırdığı
ServersServerModuleKontrol panelinde hosting hesabı, sanal makine veya oyun sunucusu sağlama
PaymentPaymentGatewayModuleTahsilat: ödeme ekranı, çekim, geri bildirim, mutabakat
RegistrarsRegistrarModuleAlan adı kaydı, yenileme ve transfer
ProductProductModule, SslProductModuleSunucusuz sağlanan ürün, örneğin SSL sertifikası
AddonsAddonModulePanele eklenen özellik: ayar sayfası, yetkiler, kancalar
SMSyok, düz sınıfSağlayıcı üzerinden kısa mesaj gönderme
Mailyok, düz sınıfGiden postayı SMTP veya sağlayıcı API ile teslim etme
Authenticationyok, düz sınıfGirişte ikinci faktör
Pipeyok, düz sınıfPosta kutusundan destek talebi oluşturma
Importsyok, düz sınıfBaşka platformdan müşteri, hizmet ve fatura taşıma
FraudFraudModuleSipariş veya kaydı puanlama
SocialAuthSocialAuthProviderSosyal giriş
Captchayok, düz sınıfAçık formu kabul etmeden sınama
Currencyyok, düz sınıfPara birimleri için kur çekme
IPyok, düz sınıfAdresi ülkeye ve ağa çözme
StorageStorageModule, CloudStorageModuleYedeklerin yüklendiği uzak hedef

Her tipte adı Sample ile başlayan kum havuzu modülleri bulunur. Belgelere göre bunlar okunmak ve kopyalanmak içindir, üretimde etkinleştirmek için değil. Yeni bir modüle başlamanın en güvenli yolu ilgili tipin Sample modülünü incelemektir.

Dizin düzeni: hangi dosya ne zaman okunur

Zorunlu tek dosya sınıf dosyasıdır; diğerleri platformun adıyla aradığı isteğe bağlı dosyalardır. Belgelerdeki dosya ağacı şöyledir:

bash
coremio/modules/{Type}/{Name}/
    {Name}.php       # ZORUNLU: sınıf, dizinle aynı adı taşır
    config.php       # dizi döndürür; ayarlar, künye, alan tanımları
    logo.png         # ya da .svg/.webp/.jpg
    hooks.php        # Hook::add() kayıtları, HER istekte dahil edilir
    AdminArea.php    # kendi admin sayfanız
    router.php       # include + ModuleAdminArea::register()
    lang/
        en.php       # pratikte ZORUNLU: geri düşülen dil
        tr.php       # çevrilen dil başına bir dosya
    pages/           # ayar ve yönetim işaretlemesi (alternatif ad: views/)
    controllers/     # adlandırılmış giriş noktaları
    assets/          # style/, js/, images/
    src/             # kendi yardımcı sınıflarınız, otomatik YÜKLENMEZ
DosyaZorunluNe zaman okunur
{Name}.phpEvetBir örnek kurulurken
config.phpPratikte evetHer yüklemede, sınıfla ya da sınıfsız
lang/en.phpEvetHer yüklemede; etkin dilin dosyası yoksa geri düşüş
hooks.phpİsteğe bağlıHer istekte, diskteki her modül için, modül etkin olsun olmasın
AdminArea.php ve router.phpİsteğe bağlıHer istekte, yönlendirmeden önce
src/İsteğe bağlıYalnız siz include ettiğinizde

Birbirine uyması gereken üç ad ve sınıf çözümlemesi

Dizin adı, sınıf dosyası adı ve sınıf adı birebir aynı olmalıdır; harfe duyarlı dosya sistemlerinde cPanel ile CPanel farklıdır. Fabrika bir örnek kurarken şu üç sınıf adını sırayla dener ve var olan ilki kazanır:

php
$classList = [
    $name . "_Module",                                       // eski sonek biçimi
    $name,                                                   // global ad alanı
    "WISECP\\Modules\\" . ucfirst($type) . "\\" . $name,      // yeni modüllerin kullandığı biçim
];

Belgeler yeni modülleri üçüncü biçimde, yani WISECP\Modules\{Type} ad alanında yazmanızı söyler. Bu ad alanının içinde niteliksiz yazılan bir çekirdek sınıf adı (ör. Utility) modül ad alanına çözülür ve lint aşamasında değil çalışma anında hata verir. Çekirdek sınıfları use ile içe aktarın ya da başlarına ters eğik çizgi koyun (\Utility, \Modules).

Modules::getInstance ve kayıt defteri

Modules::getInstance ve kayıt defteri: getInstance(), Load(), Config()

Modules sınıfı tamamen statik bir kayıt defteri ve fabrikadır. Günlük kullanımda ihtiyaç duyacağınız imzalar belgelerde birebir şöyledir:

php
public static function getInstance(string $type, string $name, array $params = []): ?object;
public static function Load($type = '', $name = '', $nominc = false, $status = '');
public static function Config($type, $module);
public static function Lang($type, $module, $lang = '');
public static function getName(string $type, string $module): string;
  • getInstance(): Sınıf dosyasını dahil eder, yapılandırma ve dil özelliklerini doldurur, eksik zorunlu yapıcı argümanlarını null ile tamamlar ve örneği tip, ad ve parametrelere göre önbelleğe alır. Aynı istekteki iki çağrı aynı nesneyi döndürür.
  • Load(): Üçüncü argüman $nominc = true ise sınıf dosyasına dokunmadan yalnız config.php ve dil dosyasını okur. Tüm tipi taramak için ad olarak birebir 'All' dizesini geçin.
  • Config(): Yalnız önbelleği okur; daha önce yükleme yapılmadıysa null döner. Lang() ise dosyayı kendisi yükler.
php
$module = Modules::getInstance("Currency", "AcmeRates");

// Tipe değil sözleşmeye göre koruyun.
if ($module && method_exists($module, "exchange_rates"))
    $rates = $module->exchange_rates("USD", ["EUR", "TRY"]);

// Sınıfı kurmadan yalnız yapılandırma ve dil.
Modules::Load("Currency", "AcmeRates", true);
$config = Modules::Config("Currency", "AcmeRates");

config.php: ayarlar ve alan tanımları

Modülün yapılandırması, dizi döndüren tek bir PHP dosyasıdır ve hem varsayılanları hem operatörün yanıtlarını tutar. Platformun okuduğu anahtarlar meta.name, meta.version, meta.logo, settings, status, fields, access_ps, show_on_adminArea ve show_on_clientArea'dır. Belgelerdeki temel biçim:

php
return [
    'meta' => [
        'name'    => 'AcmeDomains',
        'version' => '1.0',
        'logo'    => 'logo.png',
    ],
    // Kodunuzun okuduğu her anahtarı güvenli bir varsayılanla gönderin.
    'settings' => [
        'username'  => '',
        'apiKey'    => '',
        'test-mode' => 0,
    ],
];

Ayar formunu elle yazmazsınız; bir alan tanım dizisi döndürürsünüz ve admin form oluşturucu onu forma çevirir. Hangi metodu bildireceğiniz tipe bağlıdır: Registrars config_fields($settings = []), Payment argümansız config_fields(), Addons fields() kullanır. Dizi anahtarı alan adıdır, içindeki name ise etikettir. Geçerli type değerleri text, password, textarea, dropdown, radio, switch, approval, file, output ve javascript'tir.

Dil dosyaları

Her dil kodu için lang/ altında düz bir dizi döndüren bir PHP dosyası bulunur. Platform iki anahtarı okur: modül listesindeki etiket olan name ve altındaki cümle olan description. Geri düşüş dosya başınadır, anahtar başına değil: etkin dilin dosyası varsa yalnız o dosya yüklenir, orada tanımlanmamış bir anahtar İngilizceye düşmez. Bu nedenle her dosyada aynı anahtar listesini tutun ve sınıfta her zaman varsayılanla okuyun:

php
// lang/tr.php : en.php ile AYNI anahtarlar, değerler çevrilmiş
return [
    'name'         => 'Acme Kurları',
    'description'  => 'Acme sağlayıcısından döviz kurları. API anahtarı gerekir.',
    'error-no-key' => 'API anahtarı tanımlı değil.',
];

// Sınıf içinde null güvenli okuma
throw new \Exception($this->lang['error-no-key'] ?? 'API anahtarı tanımlı değil.');

Modül yaşam döngüsü

Modül yaşam döngüsü: Diskte, Kancalar kaydedilir, Yüklenir, Kurulur

Belgeler iki kavramı ayırır: mevcut dizinin diskte olması, etkin ise operatörün modülü seçmiş olmasıdır. Kapalı olmak kodunuzun yüklenmesini engellemez; özellikle hooks.php her istekte, modül kapalı olsa bile çalışır.

AşamaNeyle olurModülünüzde ne çalışır
DiskteDizin kopyalanır veya panelden yüklenirHiçbir şey
Kancalar kaydedilirHer istekte, durumdan bağımsızhooks.php baştan sona
YüklenirKayıt defterinden modül istenirconfig.php ve dil dosyası önbelleğe okunur
KurulurFabrikadan nesne istenirTaban yapıcı, sonra sizinki
EtkinleşirOperatör açaractivate(), ardından enable(); ikisi de isteğe bağlı
KapanırOperatör kapatırdeactivate(), ardından disable()
SilinirModül listesindeki silme eylemiuninstall(), dosyalara dokunulmadan önce

Etkinlik işaretinin nerede durduğu da tipe bağlıdır. Addons, Product, Fraud ve SocialAuth kendi config.php dosyasında status tutar. Servers tipinde hiçbir yerde işaret yoktur: modülü adlandıran bir sunucu kaydı onu kullanıma sokar. Registrars için bunu yapan, modülü gösteren alan adı uzantısıdır. enable() her yeniden etkinleştirmede tekrar koştuğu için idempotent yazılmalı; disable() veri silmemeli, veri silme yalnız uninstall() içinde olmalıdır. Belgelere göre uninstall() metodunu yalnız eklenti silme eylemi ve Authentication tipi çağırır.

Altın kural: fork etme, genişlet

WISECP belgelerinin en çok vurguladığı ilke, çekirdek dosyalarını düzenlememektir. Yükseltme koşusu sürümün getirdiği çekirdek dosyalarının üzerine bayt bayt yazar; sizin düzenlemeniz gider ve yedek kopya da sizin düzenlemenizi değil önceki sürümü geri getirir. Paketin ne gönderdiği ne de adını verdiği bir dizin ise hiç dokunulmadan kalır: modülünüz, kanca dosyanız ve temanız burada yaşar. Belgelerdeki altı kural özetle şöyledir:

  • Kaydedin, asla düzenlemeyin: Davranış eklemek yeni bir dosyaya mal olmalı, değişmiş bir çekirdek dosyasına değil.
  • Bir dizine sahip olun, birini işgal etmeyin: Tümüyle size ait bir dizin yükseltme listesine görünmez.
  • Konumlara değil adlara bağlanın: Kanca adları, POST alan adları ve config anahtarları sözleşmedir; satır numaraları ve şablon işaretlemesi değildir.
  • Durumunuzu kendi deponuzda tutun: Kendi tablonuz, modülünüzün config.php dosyası ya da veritabanı destekli ayar; çekirdek yapılandırma dosyası asla.
  • Uygun nokta yoksa isteyin: Eksik genişleme noktası, çekirdeği yamalama izni değil bir taleptir.
  • Koşamayan kontrol yargı üretmez: Çalıştırılamayan bir kontrolü atlandı olarak raporlayın.

Pratik bir test olarak belgeler, kendi kodunuzda coremio/classes, coremio/controllers, coremio/helpers veya templates/admin altında düzenlediğiniz her dosyayı "gelecekteki bir arıza" olarak sayar. Değişikliği bir modül, bir kanca (hook) veya bir tema üzerinden yapın.

Modülün panele uzandığı yüzeyler

Bir modül çekirdeğe dokunmadan şu yüzeylere sahip olabilir:

  • hooks.php: Olay yakalama, değer değiştirme, ekrana işaretleme ekleme ve işlem reddetme. Dosyanın başında yapılandırmayı Modules::Load($tip, $ad, true) ile ucuzca yükleyip status kapalıysa return etmek belgelerdeki kalıptır.
  • AdminArea.php ve router.php: Kendi admin sayfanız; ModuleAdminArea::register() rota, menü ve yetki kaydını yapar. Admin alanı çözücüsü 11 tipi kabul eder; SocialAuth, Captcha, Currency, IP ve Storage modülleri admin sayfası açamaz.
  • API ucu: filter:api.routes kancasına rota ekleyerek modül metodunuzu REST ucu olarak yayınlarsınız; ayrıntılar WISECP API kullanımı yazısında.
  • Müşteri paneli köprüsü: Eklenti modüllerinde adı use_ ile başlayan metotlar use_addon_method operation'ı üzerinden tarayıcıdan çağrılabilir.

Sık Sorulan Sorular

Modülümü panelde görünür yapmak için bir yere kaydetmem gerekir mi?

Hayır. Doğru tip dizininde, adı sınıf dosyasıyla eşleşen bir dizin oluşturduğunuzda modül bir sonraki istekte listelenir. Görünen adı lang/{dil}.php içindeki name anahtarından gelir.

Hatayı nasıl bildirmeliyim, false mu döndürmeliyim?

Belgelere göre hatayı insanın okuyabileceği bir mesajla Exception fırlatarak bildirin. $error özelliğine atama yapıp false döndürmek önceki ana sürümden kalmadır.

Kapattığım modülün kancaları neden hâlâ çalışıyor?

Kanca dosyaları durum kontrolü yapılmadan her modül dizininden toplanır. Dinleyicilerinizi modülün kendi etkinlik işaretiyle kapılayın.

Kendi API istemcimi yapıcıda kurabilir miyim?

Önerilmez. Yapılandırma ve dil yapıcıda hazırdır ama hizmet, ürün ve seçenekler sonradan bağlanır. Belgeler istemciyi ilk kullanımda tembel kurmanızı söyler.

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 kanca kullanımı · WISECP sunucu modülü yazma · WISECP ödeme geçidi modülü · WISECP API kullanımı · WISECP tema geliştirme · PHP nedir