Kancalar Nasıl Çalışır

1.8k görüntülenme Markdown

Çekirdek dosyalarına dokunmadan sistemin akışına girmenin yolu: bir ad, bir sıra numarası ve çalışacak bir işlev.

Genel Bakış

Kanca, çekirdeğin durup "burada birinin söyleyeceği var mı?" diye sorduğu noktadır. Sipariş kaydedilir ve sorar; fatura toplamı hesaplanır ve sorar; yönetim ekranı çizilmeden önce sorar. Siz bir işlev bırakırsınız, çekirdek o noktaya geldiğinde onu çağırır.

Bunun aldığı yer şudur: çekirdeği düzenlemeden davranış eklenir. Düzenlenen bir çekirdek dosyası ilk güncellemede geri gelir; kanca dinleyicisi kendi dosyanızda durur ve güncellemeden etkilenmez. Modüllerin sisteme bağlanma biçimi de budur.

Bu kurulumda 1012 kanca noktası vardır ve konuya göre on yedi alana ayrılır. Adın önündeki sözcük ne için açıldığını söyler.

action Olan bitti, haber veriliyor. Dönüşünüze bakılmaz — dış bir sisteme yazmak, kayıt düşmek, bildirim atmak için. 307 kanca.
filter Bir değer elinizden geçiyor ve onu değiştirebilirsiniz: tutar, liste, sorgu, şablon verisi. 215 kanca.
gate Bir işlem yapılmadan önce izin soruluyor; hayır diyerek durdurabilirsiniz. 133 kanca.
ui Bir ekranın belirli yerine kendi işaretlemenizi koyarsınız. En kalabalık aile: 346 kanca.
register Sisteme yeni bir yetenek tanıtırsınız: yol, pano parçası, rapor. 11 kanca.

Ön Koşullar

  • Dinleyicinizin yaşayacağı bir dosya: kurulumun kendi coremio/hooks dizininde bir .php dosyası ya da bir modülün hooks.php dosyası.
  • Kurulumu tamamlanmış bir sistem. Kurulum sihirbazı bitmeden hiçbir dinleyici yüklenmez (aşağıdaki tuzaklara bakın).
  • Bağlanacağınız kancanın tam adı. Ad yanlışsa hiçbir şey olmaz ve hata da almazsınız.

Yapı

Dinleyici dosyaları kendiliğinden okunur; hiçbir yere kayıt yaptırmazsınız. İki yer taranır ve ikisi de aynı anda yüklenir.

yükleme
coremio/hooks/*.php                     # kurulumun kendi dinleyicileri
coremio/modules/{Tip}/{Ad}/hooks.php    # her modülün kendi dinleyicileri

Yükleme ilk kanca çalıştığında olur, sayfa açılışında değil. Dosyalar bir kez okunur ve o istek boyunca bellekte kalır. Yani bir dinleyici eklemek için hiçbir şeyi yeniden başlatmanız gerekmez: dosyayı koyarsınız, sonraki istekte çalışır.

Bir kancanın kaç dinleyicisi olduğu sınırsızdır. Hepsi sıra numarasına göre çalışır; küçük sayı önce gider.

Referans

Dinleyici kaydetme

imza
// Hook sinifi — 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. Aynı sayı iki kez verilemez: ikinci dinleyici bir sonraki boş sayıya kaydırılır, yani kayıt sırası belirleyici olur.
$properties Çalışacak şey. Dört biçimden biri (aşağıda).

Dört dinleyici biçimi

biçimler
// 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 BIR 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 anahtari YOKSA sinif kurulur ve NESNE donus degeri olur
Hook::add('register:routes', 10, ['class' => 'AcmeRoutes']);
5.0-beta.4'ten itibaren düz PHP çağrılabilirleri de çalışır

5.0-beta.4'ten itibaren dinleyici herhangi bir PHP çağrılabiliri de olabilir: [$nesne, 'metot'], ['AcmeGuard', 'allow'], 'AcmeGuard::allow' metni ya da __invoke taşıyan bir nesne. 5.0-beta.3'e kadar bu biçimler kabul ediliyor ama hiç çalışmıyordu: her çağrı düşüyor, yalnız hata kaydında "Hook execution error" görünüyordu. Eklentiniz eski sürümlerde de çalışacaksa yukarıdaki dört biçimden birini ya da AcmeGuard::allow(...) yazımını kullanın.

Çekirdek kancayı nasıl çalıştırır

imza
static function run(string $name, mixed ...$args): array;
static function runRefs(string $name, mixed &...$args): array;
static function runDetailed(string $name, mixed ...$args): array;
Hook::run() Argümanların kopyasını geçirir. Dinleyicinin değişkende yaptığı değişiklik çağırana dönmez; dönüşler bir dizide toplanır.
Hook::runRefs() Argümanları referansla geçirir: dinleyici imzasında &$x yazarsa çağıranın değişkenini değiştirir. filter ailesinin çalışma biçimi budur.
Hook::runDetailed() Her dinleyicinin kaynak dosyası, satırı, dönüşü ve hatası ile döner. Yönetim panelindeki "bunu kim dinliyor" ekranı bunu kullanır; teşhis için de doğru araç budur.

Üçünün de ortak davranışı: 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.

Örnek

Bir dosya, üç dinleyici, üç farklı iş: olayı yakalamak, değeri değiştirmek ve bir işlemi durdurmak.

coremio/hooks/acme.php
<?php

// 1 — OLAY: siparis yazildi, disari haber ver. Donusumuze bakilmaz.
Hook::add('action:order.created', 10, function ($order) {
    Crm::push((int) $order['id'], $order);
});

// 2 — DEGER: listeyi degistir. Ilk argumana & koyarsak cagiranin degiskeni degisir.
Hook::add('filter:admin.table.rows', 10, function (&$row, $table) {
    if ($table === 'services') $row['name'] = strtoupper($row['name'] ?? '');
});

// 3 — IZIN: bos olmayan bir string donmek islemi durdurur ve o metin kullaniciya gosterilir.
Hook::add('gate:order.checkout', 10, function ($member, $items) {
    if (Blocklist::has((int) ($member['id'] ?? 0)))
        return 'Bu hesap siparis veremez.';
    return null;                    // null ya da bos string: akis devam eder
});

Dosyayı koyduğunuz an biter. Kayıt, derleme ya da yeniden başlatma yoktur; bir sonraki istekte üçü de çalışır.

Tuzaklar

Yanlış ad hiçbir şey söylemez

Var olmayan bir kanca adına dinleyici bağlamak hata vermez; dinleyici yalnızca hiç çalışmaz. Bir dinleyici "çalışmıyorsa" ilk bakılacak yer koda değil adadır; adı kanca dizininden doğrulayın, hafızadan yazmayın.

Boş argüman geçilmez, sonrakiler kayar

Çekirdek dinleyicinin parametrelerini sırayla bağlar ve boş (null) bir argümanı atlar. Atlanan yer kapanmaz: ondan sonraki argümanlar bir sola kayar ve ikinci parametre birincinin yerine düşer. İsteğe bağlı bir bağlam değerini boş geçmeyin; ya hiç geçmeyin ya da boş dize, boş dizi gibi bir yer tutucu verin.

Dönüş dizisi dinleyici sırasıyla hizalı değil

Toplanan dizi yalnız boş olmayan dönüşleri taşır. Üç dinleyiciden biri boş dönerse dizide iki eleman olur ve birinci eleman artık birinci dinleyici değildir. "İlk sonucu al" varsayımı yalnız tek dinleyicili kancalarda güvenlidir.

Fazladan parametre dinleyiciyi düşürür

Kanca iki değer fırlatırken üç parametreli bir dinleyici yazarsanız çağrı hata verir; hata yakalanır, kaydedilir ve dinleyici atlanır. Dışarıdan görünen şey "çalışmıyor"dur. Dinleyicinin kaç değer aldığını kanca kaydından doğrulayın; fazlasını değil, eksiğini yazmak güvenlidir.

Addaki önek niyeti söyler, mekanizmayı değil

Bir ad filter: ile başlıyor diye değerin referansla geldiği garanti değildir. Ölçüldüğünde filter ailesinin bir bölümü kopyayla çağrılıyordu. Bir kancanın değeri gerçekten değiştirip değiştiremeyeceğini adından çıkarmayın; kanca kaydındaki mekanizma satırından okuyun.

Kurulum bitmeden hiçbir dinleyici yüklenmez

Kurulum damgası boşken kanca dosyalarının hiçbiri okunmaz. Kurulum sihirbazı akışına kanca ile müdahale etmeyi beklemeyin; orası kanca öncesi topraktır.

Faydalı oldu mu?

Geri bildiriminiz için teşekkürler!

Hâlâ Yardıma mı İhtiyacınız Var?

Yukarıda bulamadığınız her şey için destek ekibimiz her zaman yanınızda.