WISECP'de kanca (hook), çekirdeğin bir işlemin ortasında durup "burada söyleyecek biri var mı?" diye sorduğu noktadır. Kendi dosyanıza Hook::add('kanca:adi', oncelik, islev) ile bir dinleyici bırakırsınız; çekirdek o noktaya geldiğinde işlevinizi çağırır. Böylece çekirdek dosyalarına tek satır dokunmadan sipariş, fatura, giriş veya ekran davranışını değiştirebilirsiniz ve bu değişiklik güncellemelerde silinmez.
Bu yazıda resmî geliştirici belgelerine dayanarak beş kanca ailesini, Hook::add imzasını, öncelik davranışını, dinleyici dosyalarının yerini, run, runRefs ve runDetailed farkını, hata yönetimini ve belgelerden birebir alınmış üç gerçek örneği anlatıyoruz. Kancaların modül içinden nasıl taşındığını görmek için WISECP modül geliştirme rehberi, platformun genel tanıtımı için WISECP nedir yazısına bakabilirsiniz.
Beş kanca ailesi

Belgelere göre kurulumda 984 kanca noktası vardır ve konuya göre on yedi alana (client, admin, user, service, domain, ticket, product, invoice, module, order, money, cron, knowledgebase, payment, notification, ssl, template) ayrılır. Adın önündeki sözcük kancanın ne için açıldığını söyler:
| Aile | Ne için | Belgedeki sayı | Tipik dönüş sözleşmesi |
|---|---|---|---|
| action | Olan bitti, haber veriliyor | 301 | Dönüş yoksayılır |
| filter | Bir değeri değiştirme | 199 | Çoğunda değer referansla değiştirilir |
| gate | İşlemden önce izin sorma | 131 | Boş olmayan string işlemi durdurur |
| ui | Ekranın belirli yerine işaretleme koyma | 342 | Çoğunda basılacak HTML döndürülür |
| register | Yeni yetenek tanıtma: yol, pano parçası, rapor | 11 | Kayıt dizisi veya nesneye ekleme |
Dinleyici dosyaları nerede durur
Dinleyici dosyaları kendiliğinden okunur; hiçbir yere kayıt yaptırmazsınız. İki yer taranır:
coremio/hooks/*.php # kurulumun kendi dinleyicileri
coremio/modules/{Tip}/{Ad}/hooks.php # her modülün kendi dinleyicileriYükleme sayfa açılışında değil, ilk kanca çalıştığında olur ve dosyalar istek boyunca bellekte kalır. Yeniden başlatma gerekmez: dosyayı koyarsınız, sonraki istekte çalışır. Belgeler bir ayrım daha yapar: coremio/hooks dizinine bırakılan serbest bir dosya yalnız o sisteme aittir, paket sistemine görünmez; birden çok sisteme gidecek davranış bir modül dizininin hooks.php dosyasında yaşamalıdır. Ayrıca kurulum sihirbazı tamamlanmadan hiçbir dinleyici yüklenmez.
Hook::add imzası ve dört dinleyici biçimi

// Hook sınıfı: coremio/classes/Hook.php
static function add(string $name, int $priority, callable|array $properties): void;- $name: Bağlanılacak kancanın tam adı. Doğrulanmaz; yanlış ad sessizce hiçbir şeye bağlanır.
- $priority: Çalışma sırası; küçük olan önce çalışır.
- $properties: Çalışacak şey; aşağıdaki dört biçimden biri.
// 1: kapanış (en yaygını)
Hook::add('action:order.created', 10, function ($order) {
Crm::push($order['id']);
});
// 2: sınıf metodu; sınıf BİR KEZ kurulur ve tüm kancalarda paylaşılır
Hook::add('filter:invoice.late_fee_amount', 10, ['class' => 'AcmeBilling', 'method' => 'adjust']);
// 3: statik metot; nesne kurulmaz
Hook::add('gate:order.checkout', 10, ['class' => 'AcmeGuard', 'method::static' => 'allow']);
// 4: kurucu; metot anahtarı YOKSA sınıf kurulur ve nesne dönüş değeri olur
Hook::add('register:routes', 10, ['class' => 'AcmeRoutes']);Örneklerdeki Crm, AcmeBilling ve AcmeGuard sizin yazacağınız sınıflardır; WISECP çekirdeğinin parçası değildir.
Öncelik (priority) nasıl davranır
Küçük sayı önce çalışır. Belgelerin vurguladığı ince nokta şudur: aynı sayı iki kez alınamaz. İkinci dinleyici bir sonraki boş sayıya kaydırılır, yani iki dinleyiciye aynı sayıyı vermek onları eşit yapmaz; hangisinin kaydığı dosyaların yüklenme sırasına bağlıdır ve modül eklendikçe değişebilir. Sırası önemli dinleyicilere ayrı sayılar verin.
- Bir değeri son sözü siz söyleyerek değiştirmek istiyorsanız büyük sayı verin.
- Bir işlemi herkesten önce durdurmak istiyorsanız küçük sayı verin.
- Varsayılan öncelik yoktur; sayıyı her zaman bilinçli geçin.
run, runRefs ve runDetailed: çekirdek kancayı nasıl çalıştırır
static function run(string $name, mixed ...$args): array;
static function runRefs(string $name, mixed &...$args): array;
static function runDetailed(string $name, mixed ...$args): array;| Metot | Argümanlar | Kullanım |
|---|---|---|
| Hook::run() | Kopya olarak | Dinleyicinin değişkende yaptığı değişiklik çağırana dönmez; boş olmayan dönüşler bir dizide toplanır. |
| Hook::runRefs() | Referansla | Dinleyici imzasında &$x yazarsa çağıranın değişkenini değiştirir; filter ailesinin çalışma biçimi. |
| Hook::runDetailed() | Kopya olarak | Her dinleyicinin kaynak dosyası, satırı, dönüşü ve hatasıyla döner; teşhis aracı. |
Hata yönetimi üçünde de aynıdır: bir dinleyici hata fırlatırsa yakalanır, kaydedilir ve sıradakine geçilir. Tek bir bozuk dinleyici ne çekirdeği durdurur ne de diğer dinleyicileri engeller. Bunun bedeli, hatanızın sessiz kalmasıdır. Belgelerdeki teşhis sırası:
- Hata günlüğünde
Hook execution errorkaydı varsa dinleyici koşmuş ve patlamıştır. Hook listener unresolvedkaydı sınıf veya metot adının yanlış olduğunu gösterir.- Günlük boşsa dinleyici hiç çağrılmamıştır: ad yanlıştır ya da dosya taranan iki yerde değildir.
- Kesin cevap için kancayı teşhis kipinde çalıştırın:
foreach (Hook::runDetailed('action:service.created', $id, $data) as $row) {
echo $row['source']['file'] . ':' . $row['source']['line'] . "\n";
if ($row['error'] !== null) echo ' HATA: ' . $row['error'] . "\n";
}Üç gerçek örnek

Aşağıdaki kanca adları, parametre sıraları ve dönüş sözleşmeleri WISECP kanca kayıtlarından birebir alınmıştır. Accounting sizin muhasebe entegrasyon sınıfınızı temsil eder.
1. Fatura ödendiğinde muhasebeye bildirmek (action)
action:invoice.status_changed durum yazıldıktan sonra çalışır ve dört parametre verir: yeniden okunmuş güncel fatura $invoice, yeni durum $status, önceki durum $old_status ve geçiş seçenekleri $options. Dönüş yoksayılır. Durum değerleri paid, unpaid, cancelled, refund ve waiting'dir.
Hook::add('action:invoice.status_changed', 10,
function ($invoice, $status, $old_status, $options) {
// Para GERÇEKTEN girdi mi? Yalnız ödenmişe geçişe tepki verin.
if ($status === 'paid' && $old_status !== 'paid')
Accounting::settled((int) ($invoice['id'] ?? 0), $options['pmethod'] ?? '');
});2. Paylaşım linkiyle yüksek tutarlı ödemeyi engellemek (gate)
gate:invoice.client_pay müşteri fatura öderken hiçbir para hareket etmeden önce çalışır. Parametreler: $invoice, faturanın sahibi $uid, çözülmüş ödeme yöntemi $method ve paylaşım bağlantısıyla mı ödendiğini gösteren $share. Boş olmayan bir string ödemeyi durdurur; komisyon kitaplanmaz, bakiye düşmez, ödeme kaydı açılmaz.
Hook::add('gate:invoice.client_pay', 10, function ($invoice, $uid, $method, $share) {
// Paylaşım ödemesinde ödeyen kimliksizdir: risk kurallarını ona göre kurun.
if ($share && (float) ($invoice['total'] ?? 0) > 5000)
return 'Bu tutar paylaşım linkiyle ödenemez.';
return null;
});Kapı kancalarında belgelerin uyarısı açıktır: kapıya iş yaptırmayın. Engelleme kancaları her denemede çalışır; içinde uzak servise istek atmak akışı yavaşlatır ve başka bir dinleyici işlemi zaten durdurmuş olabileceği için yazdığınız kayıt karşılıksız kalabilir.
3. Yönetim panosuna duyuru eklemek (ui)
ui:admin.dashboard.top panonun en üstünde, istatistik kartlarından önce görünür ve parametre almaz. Döndürdüğünüz HTML basılır; birden çok dinleyici varsa çıktılar öncelik sırasıyla art arda eklenir. Boş metin, null ve false atlanır.
Hook::add('ui:admin.dashboard.top', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});Sık yapılan hatalar
- Fazladan parametre: Kanca iki değer verirken üç parametreli dinleyici yazarsanız çağrı hata verir ve dinleyici atlanır. Eksik yazmak güvenlidir, fazla yazmak değil.
- Boş argüman kayması: Çekirdek
nullargümanı atlar ve sonraki argümanlar bir sola kayar. Kendi kancanızı çalıştırırken isteğe bağlı değeri boş geçmeyin. - Dönüş dizisi hizası: Toplanan dizi yalnız boş olmayan dönüşleri taşır; "ilk sonucu al" varsayımı yalnız tek dinleyicili kancada güvenlidir.
- Şablon değişkenleri:
filter:template.variablesreferansla çalışmaz; döndürdüğünüz dizi mevcut değişkenlerin yerine geçer. Gelen diziyi temel alıp tamamını döndürün. - Referanslı kancaya sabit değer: Kendi kancanızı
runRefsile açıyorsanız her argüman değişken olmalıdır; dizi sabiti veya fonksiyon dönüşü geçmek ölümcül hatadır.
Modül içinden kanca kaydetme kalıbı
Modülünüzün hooks.php dosyası modül kapalı olsa bile her istekte çalıştığından belgeler dosyanın başında ucuz bir durum kapısı önerir:
<?php
// Sınıfı kurmadan yapılandırmayı yükle (üçüncü argüman true).
Modules::Load('Addons', 'MyAddon', true);
$my_config = Modules::Config('Addons', 'MyAddon') ?: [];
if (!($my_config['status'] ?? false)) return;
Hook::add('action:service.created', 10, function ($id, $data) {
// Modül örneğini dosyanın başında değil, dinleyicinin içinde kurun.
});Bu kalıp, sunucu modülü veya ödeme geçidi modülü yazarken de geçerlidir. Kancalarla yetinemeyeceğiniz dış entegrasyonlar için WISECP API kullanımı yazısına bakabilirsiniz.
Sık Sorulan Sorular
Dinleyicim çalışmıyor ama hata da yok, neden?
En sık neden kanca adının yanlış yazılmasıdır; var olmayan bir ada bağlanmak hata vermez. Adı hafızadan değil kanca dizininden kopyalayın ve dosyanın coremio/hooks veya bir modülün hooks.php dosyasında olduğundan emin olun.
Aynı kancaya iki dinleyiciyi aynı öncelikle bağlarsam ne olur?
İkincisi bir sonraki boş sayıya kaydırılır. Hangisinin kaydığı yüklenme sırasına bağlı olduğundan sıra önemliyse farklı sayılar verin.
Kancada fırlattığım istisna kullanıcıya gösterilir mi?
Dinleyici içinde fırlatılan istisna yakalanır ve kaydedilir; akış sıradaki dinleyiciyle devam eder. Bir işlemi kullanıcıya mesajla durdurmak istiyorsanız gate: kancasından boş olmayan bir string döndürün.
Fatura ödendi bilgisini hangi kancadan almalıyım?
Faturanın tamamen ödendiği anı yakalamak için action:invoice.status_changed içinde $status === 'paid' kontrolü yapın. Her ödeme satırını izlemek istiyorsanız kısmi olabileceğini bilerek action:invoice.payment_recorded kullanın.
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 sunucu modülü yazma · WISECP ödeme geçidi modülü · WISECP API kullanımı · WISECP fatura ayarları · PHP nedir