İlk Modülünüz
Boş bir dizinden çalışan bir modül kurun: sınıf, yapılandırması, dil dosyaları ve yönetim panelinde görünmeye başladığı an.
Genel Bakış
Modül, adı modülün adı olan bir dizindir; içinde aynı adı taşıyan bir sınıf dosyası ve her modülde bulunan iki şey vardır: bir yapılandırma dizisi ve bir dil klasörü. Hiçbir yere kayıt yaptırmak gerekmez. Modül listesi dizini okur, yani doğru adlandırılmış bir dizin var olduğu anda bir modüldür.
Bu anlatım bir kur modülü kuruyor, çünkü gerçek bir işi olan en küçük tip odur: üç metoda cevap verir. Aynı iskelet diğer bütün tiplerin başlangıç noktasıdır; her tip bunun üzerine kendi zorunlu metotlarını ekler.
Ön Koşullar
- Düzenleyip yeniden yükleyebileceğiniz bir geliştirme kurulumu. Bozamayacağınız bir kurulum üzerinde geliştirme yapmayın.
coremio/modulesdizinine yazma yetkisi.- Kod tabanının kendine uyguladığı konvansiyonlar, çünkü bir modül de çekirdek kod gibi okunur ve gözden geçirilir.
Yapı
Dört yol var ve adlar serbest değil: dizin, sınıf dosyası ve sınıf aynı adı taşır.
coremio/modules/Currency/AcmeRates/
├── AcmeRates.php # sınıf, dizinle aynı adı taşır
├── config.php # dizi döndürür; ayarlar kaydedilince modül bu dosyayı yeniden yazar
└── lang/
├── en.php # dizi döndürür; panelde görünen 'name' ve 'description'
└── tr.php
Currency). Sınıfın hangi sözleşmeyi karşılayacağını ve panelin onu nerede listeleyeceğini belirler.
WISECP\Modules\{Tip}. Çekirdek sınıflara bu yüzden baştaki ters eğik çizgiyle erişilir.
Adım Adım
Dizini Oluşturun
coremio/modules/Currency/AcmeRates/dizinini oluşturun.- İçine
lang/klasörünü açın. - Panel modülü henüz listelemez: yükleyecek bir sınıfı yoktur.
Sınıfı Yazın
- Ad alanını, sınıfı ve her modülün tanımladığı üç özelliği içeren
AcmeRates.phpdosyasını oluşturun. - Yapılandırmayı ve dil paketini kurucuda yükleyin ki sınıfın geri kalanı okuyabilsin.
- Tipin zorunlu tuttuğu metotları uygulayın; sözleşme aşağıda listeli.
- Modüller ekranını yenileyin; modül dil dosyasındaki adıyla listelenir.
Yapılandırmayı Ekleyin
- Modülünüzün ihtiyaç duyduğu ayarları boş ya da güvenli varsayılanlarla döndüren
config.phpdosyasını oluşturun. save_config()metodunu, gönderilen değerleri diziyle birleştirip dosyayı geri yazacak şekilde uygulayın.- Dosyayı ham yazma yerine dosya yöneticisiyle yazın: yapılandırma dosyası PHP'dir ve derlenmiş eski kopya, kayıttan sonra da eski değerleri sunmaya devam eder.
- Panelden bir ayar kaydedip yenileyin; geri okuduğunuz değer yeni değer olmalıdır.
Dil Dosyalarını Ekleyin
- Her biri dizi döndüren
lang/en.phpvelang/tr.phpdosyalarını oluşturun. - İkisine de
namevedescriptionanahtarlarını yazın: modül listesinin bastığı iki anahtar bunlardır. - Listeyi yenileyin; modül artık dizin adı yerine kendi adını gösterir.
Referans
Bir Kur Modülü Neyi Uygulamak Zorunda
Türetilecek bir taban sınıf yoktur. Sözleşme, çekirdeğin gerçekten çağırdığı metotlar kümesidir ve her tipin kendi kümesi vardır. Currency için üç tanedir:
// Kur çekme. Money::get_exchange_rates() ve panelin bağlantı testi çağırır; test önce
// method_exists ile varlığını kontrol eder. $to hedef kodları taşır, büyük harfle.
// KOD => kur haritası döndürün; falsy her dönüş başarısızlık sayılır.
public function exchange_rates(string $from = '', array $to = []): array|false;
// Ayar kalıcılığı. Kur ayarları operasyonu bunu yalnız bu modüle gönderilen
// değerlerle, yani $_POST['module_data']['AcmeRates'] ile çağırır.
public function save_config(array $data = []): bool;
// Kur ekranında gösterilen ayar işaretlemesi. Instance üzerinde koşulsuz çağrılır,
// yani boş dize döndürecek olsa bile var olmak zorundadır.
public function page_settings(): string;
module_data[{ModülAdı}][{anahtar}] olarak adlandırılmalıdır; save_config() tam bu şekli alır. Başka adlı bir alan modüle hiç ulaşmaz.
name yoksa liste önce config['name']'e, sonra dizin adına düşer.
Modülün Çağırdığı Çekirdek Metotlar
// Modules : fabrika ve iki yükleyici. Hepsi statik.
public static function getInstance(string $type, string $name, array $params = []): ?object;
public static function Config($type, $module); // cache'ten; önce yükleme ister
public static function Lang($type, $module, $lang = ''); // dosyayı kendisi yükler
public static function Load($type = '', $name = '', $nominc = false, $status = '');
public static function getName(string $type, string $module): string;
public static function save_log($type = '', $module = '', $action = '', $request = '', $response = '', $processed = '');
// Utility : istek ve JSON yardımcıları.
public static function HttpRequest($url = '', $params = [], $retry = 0); // dizi ilk argüman, aşağıya bakın
public static function jdecode($string = '', $mode = false); // ilişkisel dizi için $mode = true
public static function jencode($string = '', $flags = 0): string|false;
public static function array_export($array = [], $options = []); // ['pwith' => true] PHP dosyası olarak sarar
// FileManager : derlenmiş kopyayı geçersiz kılan yazım.
public static function file_write($file, $data = null, $mode = 'w', $flags = 0);
HttpRequest() iki biçimlidir; ilk argüman olarak dizi geçin, gerisi yok sayılır:
urlencode() ile kurun; sizin yerinize hiçbir şey kaçırılmaz.
'GET'. Gövde yalnız metot GET değilken gönderilir.
['Authorization: Bearer ' . $key, 'Content-Type: application/json'].
Örnek
Sınıfın tamamı, sonra okuduğu iki dosya. Her modülün tanımladığını tanımlar, tipinin istediği üç metoda cevap verir ve hatayı platformun geri kalanının bildirdiği gibi bildirir.
namespace WISECP\Modules\Currency;
class AcmeRates
{
public string $name = "AcmeRates";
public ?array $config = null;
public ?array $lang = null;
public function __construct()
{
$this->config = \Modules::Config("Currency", $this->name);
$this->lang = \Modules::Lang("Currency", $this->name);
}
public function save_config(array $data = []): bool
{
$merged = array_replace_recursive($this->config ?: [], $data);
return (bool) \FileManager::file_write(__DIR__ . DS . "config.php", \Utility::array_export($merged, ['pwith' => true]));
}
public function exchange_rates(string $from = '', array $to = []): array|false
{
$key = (string) ($this->config['apiKey'] ?? '');
if ($key === '')
throw new \Exception($this->lang['error-no-key'] ?? 'API anahtarı tanımlı değil.');
$response = \Utility::HttpRequest([
'url' => 'https://api.example.com/rates?base=' . urlencode($from),
'type' => 'GET',
'header' => ['Authorization: Bearer ' . $key],
]);
// Her çağrı kaydedilir; böylece hata veren sağlayıcı panelden teşhis edilebilir.
\Modules::save_log("Currency", $this->name, "exchange", ['from' => $from, 'to' => $to], $response);
$data = \Utility::jdecode((string) $response, true);
if (!isset($data['rates']))
throw new \Exception('Kur sağlayıcısından beklenmeyen yanıt.');
$out = [];
foreach ($to as $code) $out[$code] = (float) ($data['rates'][$code] ?? 0);
return $out;
}
public function page_settings(): string
{
$key = htmlspecialchars((string) ($this->config['apiKey'] ?? ''), ENT_QUOTES);
// Alan adı sözleşmenin kendisidir: save_config() tam bunu alır.
return '<div class="row mb-0 align-items-center">'
. '<label class="col-sm-3 col-form-label fw-semibold">API Key</label>'
. '<div class="col-sm-9"><input type="text" class="form-control" '
. 'name="module_data[AcmeRates][apiKey]" value="' . $key . '"></div></div>';
}
}
// config.php : page_settings() bastığı ve save_config() geri yazdığı anahtarlar.
return [
'apiKey' => '',
'help-link' => 'https://api.example.com/docs',
];
// lang/tr.php : modül listesinin gösterdiği 'name' ve 'description'.
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.',
];
Diğer yarı: platform modüle nasıl ulaşır. Modülü asla new ile kurmayın; sınıfı yükleyen, yapılandırmayı dolduran ve nesneyi cache'leyen şey fabrikadır.
$module = Modules::getInstance("Currency", "AcmeRates");
// Tipe değil sözleşmeye göre koruyun: modül düz bir sınıftır ve bir metottan eski olabilir.
if ($module && method_exists($module, "exchange_rates"))
$rates = $module->exchange_rates("USD", ["EUR", "TRY"]);
// Hiçbir şey kurmadan yalnız yapılandırma ve dil paketi.
Modules::Load("Currency", "AcmeRates", true);
$config = Modules::Config("Currency", "AcmeRates");
$label = Modules::getName("Currency", "AcmeRates");
Tuzaklar
Modül bir sorunu, operation'ın yaptığı gibi bildirir: insanın okuyabileceği bir mesajla fırlatır. Çağıran taraf yakalar ve o mesajı ekranda gösterir. return false ile birlikte set edilen bir $error özelliği önceki ana sürümden kalmadır. Eski portlarda göreceksiniz ama yeni kod onu kullanmaz.
Dosya yöneticisiyle yazın. Ham yazma, önceden derlenmiş kopyayı yerinde bırakır ve panel gerçekte başarılı olmuş bir kayıttan sonra eski değeri gösterir.
Modül dosyasında yazılan Utility::jdecode(...), WISECP\Modules\Currency\Utility olarak aranır ve lint aşamasında değil çalışma anında patlar. Çekirdek sınıfların önüne ters eğik çizgi koyun ya da import edin.
Modülün kendi kaynak klasörüne koyduğunuz bir sınıf sıradan PHP'dir ve new ile kurulur. Ayrıca otomatik yüklenmez, kullanmadan önce dahil edin. Fabrika yalnız platformun tanıdığı modül tipleri içindir.
İlgili Makaleler
Geri bildiriminiz için teşekkürler!
Yukarıda bulamadığınız her şey için destek ekibimiz her zaman yanınızda.