SMS Modülü Yazma
SMS modülü, metin mesajını bir geçide teslim eden sürücüdür. Mail'den farklı olarak üç iş yapar: bildirim, uluslararası gönderim ve bazen fiyat ile teslim raporlaması.
Genel Bakış
Taban sınıf yoktur. Sözleşme Mail gibi ördek tiplemesine dayanır: çekirdek, dizin adını taşıyan sınıfı yükler ve bilinen metotları çağırır.
İki config anahtarı sürücü gösterir: modules/sms bildirimler, modules/sms-intl uluslararası trafik için. Yurt içi geçit yabancı numaraları ikincisine devreder, bu yüzden iki kova tutulur.
Üçüncü yol modülündür: controllers/ dosyalarınız sürücüyü kaydedilmemiş kimlik bilgileriyle kurabilir.
Ön Koşullar
coremio/modules/SMS/altına yazma erişimi.- Geçit kimlik bilgileri ve genelde kayıtlı bir gönderici kimliği.
- Geçidiniz yurt içi mi, uluslararası mı? Yetenek işaretlerini bu belirler.
- Mail Modülü Yazma.
Yapı
Dizin, dosya ve sınıf adı aynı dizedir, ad alanı yoktur.
coremio/modules/SMS/Acme/
├── Acme.php sürücü sınıfı, adı Acme, ad alanı yok
├── config.php künye (uluslararası bayrağıyla) + kaydedilmiş kimlik bilgileri
├── Source/class.php isteğe bağlı geçit istemcisi, kurucu tarafından dahil edilir
├── lang/en.php
├── lang/tr.php
└── logo.png isteğe bağlı, config meta.logo ile gösterilir
Adım Adım
Sürücü Sınıfını Kurma
coremio/modules/SMS/Acme/Acme.phpdosyasını açıpclass Acmetanımlayın.- Yetenek işaretlerini public özellik olarak bildirin.
- Yapıcıda kayıtlı config'i verilen diziyle birleştirin; verilen üstün gelir.
body(),title(),AddNumber()metotlarını her biri$thisdöndürecek şekilde uygulayın.submit()uygulayın: yurt içi kovayı gönderin, ötekini devredin.getTitle(),getBody(),getNumbers(),getError()uygulayın.
Gönderici Kimliği ve Numaralar
- Göndericiyi yapıcıda config'ten doldurun.
AddNumber()üç biçimi kabul etmeli: numara, ülke kodlu numara, dizi.- Dikey çizgi taşıyan değer
ülkeKodu|numarademektir. - Devir yasaklanmadıysa sonucu ülke koduna göre kovaya yönlendirin.
- Her iki kovayı da
body()içinde sıfırlayın.
Ayarlar ve Raporlar
- Gizli alanlar, etkinleştirme kutusu ve kimlik alanlarıyla
page_settings()ekleyin. controller_save()ekleyin: değişenlericonfig.phpiçine yazın,modules/smsçevirin.- Kredi bakiyesi için
getBalance(); çekirdek çağırmaz. - Toplu gönderim kimliği için
getReportID()vegetReport()uygulayın. get_prices()yalnız uluslararası geçitler içindir.
Referans
Çekirdek Neyi Çağırır
Dağıtıcı mesajı kurar, sonra alıcıları gezer.
| Metot | Çekirdek ne zaman çağırır | Ne döndürmeli |
|---|---|---|
__construct($external_config = []) | Gönderim başına bir kez | hiçbir şey |
body($text, $template, $variables, $lang, $user) | İlk sırada; kovaları sıfırlar | $this |
use_otp() | Tek kullanımlık kod şablonlarında, body()'den sonra. Sunulduğunda. | $this |
title($arg) | Gönderici kimliği değiştirilirse | $this |
AddNumber($arg, $cc) | Alıcı başına, ya da bir diziyle | $this |
submit($isthis = false) | Alıcılar girildikten sonra | başarıda doğru değer, hatada false |
getTitle() | Başarılı gönderimden sonra | dize |
getBody() | Başarılı gönderimden sonra | dize |
getNumbers() | Başarılı gönderimden sonra | iki kova, tek dizi |
getError() | Yanlış değer dönen gönderimden sonra | hata metni |
numbers_reset() | Kendi body() metodunuz | okunmaz |
getReportID(), getReport($id), get_prices() | Sunulduğunda | aşağıya bakın |
getBalance() | Çekirdek çağırmaz | kendi biçiminiz |
Harf durumuna dikkat: dağıtıcı addNumber(), sürücüler AddNumber() yazar. PHP ikisini de aynı metoda çözer.
Metot İmzaları
public function __construct($external_config = []);
// HER İKİ alıcı kovasını sıfırlar, sonra şablon verildiyse onu işler.
// $template "group/name" biçimindedir, örn. "user/gsm-activation"; false ise $text nihaidir.
public function body($text = '', $template = false, $variables = [], $lang = '', $user = 0);
// Cihazda görünen gönderici kimliği / originator.
public function title($arg = '');
// SIRA TUZAĞI: ÖNCE numara, SONRA ülke kodu gelir.
// $arg şunları kabul eder: "5551234567", "90|5551234567", ya da ikisinden birinin dizisi.
// $cc yalnız $arg bir dizi değilken dikkate alınır.
public function AddNumber($arg = 0, $cc = null);
// $isthis = true boolean yerine sürücüyü döndürür.
public function submit($isthis = false);
public function getTitle();
public function getBody();
public function getNumbers();
public function getError();
public function numbers_reset();
// İsteğe bağlı, özellik özellik. Çekirdek her birini çağırmadan önce method_exists() ile yoklar.
public function getReportID(); // son gönderimin ürettiği toplu gönderim kimliği
public function getReport($id = 0); // bir toplu gönderim için teslim raporu
public function get_prices(); // uluslararası fiyat listesi, aşağıya bakın
public function use_otp(bool $on = true); // sağlayıcının OTP rotası; $this döndürür
// Modüle özgü konvansiyon: çekirdek bunu hiç çağırmaz. Yalnız kendi
// controllers/*.php ve pages/*.php dosyalarınızdan ulaşılır, yani argüman listesi sizindir.
public function getBalance(); // kalan kredi, ya da $error dolu olarak false
İki dönüş biçimi ada göre okunur:
// getReport(): üç adlandırılmış kova, her biri ham satırlar ve bir sayaç taşır.
// Rapor okuyucu ayrıca 'delivered' / 'sending' / 'failed' adlarını takma ad olarak kabul eder.
return [
'waiting' => ['data' => $waitingRows, 'count' => count($waitingRows)],
'conducted' => ['data' => $deliveredRows, 'count' => count($deliveredRows)],
'erroneous' => ['data' => $failedRows, 'count' => count($failedRows)],
];
// get_prices(): ülke kodu => para birimi kodu => mesaj başına maliyet.
// Config'in supported-currencies anahtarı birini belirtmedikçe kullanılabilir ilk para birimi kazanır.
return [
'TR' => ['EUR' => 0.0180],
'DE' => ['EUR' => 0.0640, 'USD' => 0.0700],
'US' => ['USD' => 0.0075],
];
get_prices() maliyetleri birincil para birimine çevrilir, sms/profit-rate marjı eklenir ve ülke haritası yeniden yazılır.
Yetenek İşaretleri
Bunlar metot değil public özelliktir. Çekirdek onları hem örnekte hem config'te okur, ikisi uyuşmalıdır.
body() sıfırlar, çekirdek use_otp() ile açar; submit() rotayı buna göre seçer.
getError() olmasına rağmen doğrudan okunur.
config.php hâli; seçici buna bakar. Özellik ile meta uyuşmalıdır.
Config Anahtarları
name anahtarı üstün gelir.
title() bundan doldurulur.
get_prices() birkaç para birimi sunarsa tercih listesi. Boşsa ilki alınır.
Crypt::encode($v, Config::get("crypt/user")) ile yazın, Crypt::decode() ile okuyun.
Hangi Sürücü Çalışır
Üçüncü çözümlemeyi yanlış yapmak, müşterinin hesabı yerine operatörün geçit hesabıyla gönderir.
| Yol | Örnek nasıl kurulur | Kullanılan kimlik bilgileri |
|---|---|---|
| Bildirimler | Adsız Modules::Load("SMS"), sonra new $smsModule() | kayıtlı config |
| Uluslararası gönderim | Modules::getInstance("SMS", Config::get("modules/sms-intl")) | kayıtlı config |
| Modülün kendi sayfaları | new Modulunuz($external) | formdan gelen değerler, kayıtlı config üzerine |
Yapıcının $external_config taşıma sebebi budur; çekirdek onu geçmez. Fabrikanın üçüncü argümanı yapıcı için konumsal argüman listesidir.
Örnek
Kendi ülkesini kapsayan ve yabancı numaraları devreden bir geçit.
"Kendi ülke kodu" geçidinizin hizmet verdiği ülkedir; config'inizden okunur. Karşılaştırmadan önce baştaki + işaretini temizleyin ve operatöre dikkat edin: != ile '90' ve '+90' eşit sayılır, !== ile sayılmaz.
<?php
defined('CORE_FOLDER') OR exit('You can not get in here!');
class Acme
{
public $international = false;
public $prevent_transmission_to_intl = false;
public $otp = false;
public $error = null;
public $lang = [];
public $config = [];
private $title = '';
private $body = '';
private $numbers = [];
private $numbers_intl = [];
public function __construct($external_config = [])
{
$this->lang = Modules::Lang('SMS', __CLASS__);
$this->config = array_merge(Modules::Config('SMS', __CLASS__) ?: [], $external_config);
$this->title = (string) ($this->config['origin'] ?? '');
}
public function title($arg = '')
{
$this->title = (string) $arg;
return $this;
}
public function body($text = '', $template = false, $variables = [], $lang = '', $user = 0)
{
// Dağıtıcı alıcı başına tek örneği yeniden kullanır; bu olmadan kovalar büyür.
$this->numbers_reset();
if ($template) {
$look = View::notifications('sms', $template, $text, $variables, $lang, $user);
if ($look !== false && isset($look['content'])) {
if (isset($look['title'])) $this->title($look['title']);
$text = $look['content'];
}
}
$this->body = (string) $text;
return $this;
}
public function use_otp(bool $on = true)
{
// Çekirdek bunu kod şablonlarında body()'den sonra çağırır; son sözü modülün kendi ayarı verir.
$this->otp = $on && (bool) ($this->config['otp'] ?? false);
return $this;
}
public function AddNumber($arg = 0, $cc = null)
{
if (!is_array($arg)) $arg = $cc ? [$cc . '|' . $arg] : [$arg];
foreach ($arg as $num) {
if (!str_contains((string) $num, '|')) {
$this->numbers[] = Filter::numbers((string) $num);
continue;
}
// Geçidin kendi ülkesi, config'inden okunur — asla sabit yazılmaz.
$home = ltrim((string) ($this->config['home_cc'] ?? ''), '+');
[$ccPart, $numPart] = explode('|', (string) $num, 2);
$ccPart = ltrim($ccPart, '+') ?: $home;
$full = $ccPart . Filter::numbers($numPart);
if (!$this->prevent_transmission_to_intl && $home !== '' && $ccPart !== $home) $this->numbers_intl[] = $full;
else $this->numbers[] = $full;
}
return $this;
}
public function getTitle()
{
return $this->title;
}
public function getBody()
{
return $this->body;
}
public function getNumbers()
{
return array_merge($this->numbers, $this->numbers_intl);
}
public function getError()
{
return $this->error;
}
public function numbers_reset()
{
$this->otp = false;
$this->numbers = [];
$this->numbers_intl = [];
return true;
}
public function submit($isthis = false)
{
if (Validation::isEmpty($this->body)) {
$this->error = 'Message content can not be left blank!';
return false;
}
if (!$this->numbers && !$this->numbers_intl) {
$this->error = 'Enter the phone number to be sent.';
return false;
}
$send = false;
// Yabancı numaralar modules/sms-intl anahtarını hangi sürücü tutuyorsa ona gider.
if (!$this->prevent_transmission_to_intl && $this->numbers_intl) {
$intl = (string) Config::get("modules/sms-intl");
if ($intl !== '' && $intl !== 'none') {
$peer = Modules::getInstance('SMS', $intl);
if ($peer) {
$send = $peer->body($this->getBody())->AddNumber($this->numbers_intl)->submit();
// Yurt içi numara kalmadı, yani karşı sürücünün sonucu sonucun tamamıdır.
if (!$this->numbers) {
$this->error = $peer->getError();
return $isthis ? $this : $send;
}
}
}
}
if ($this->numbers) {
$response = Utility::HttpRequest([
'url' => 'https://api.example.com/sms/send',
'type' => 'POST',
'data' => [
'user' => $this->config['username'] ?? '',
'pass' => Crypt::decode($this->config['password'] ?? '', Config::get("crypt/user")),
'header' => $this->title,
'message' => $this->body,
'to' => implode(',', $this->numbers),
'otp' => $this->otp ? 1 : 0,
],
]);
$decoded = Utility::jdecode((string) $response, true) ?: [];
$send = (string) ($decoded['code'] ?? '') === '00';
// Dağıtıcı yanlış değer dönüşünden sonra hatayı okur; fırlatmaları yakalamaz.
if (!$send) $this->error = $decoded['message'] ?? 'Acme refused the batch.';
}
return $isthis ? $this : $send;
}
}
Modules::Load("SMS");
$smsModule = Config::get("modules/sms");
$sms = $smsModule && $smsModule !== 'none' ? new $smsModule() : false;
// $phone "number|countryCode|lang" olarak gelir, yani parçalar konuma göre açılır.
foreach ($adminContacts['phones'] as $phone) {
$parse = explode("|", (string) $phone);
$aLang = $parse[2] ?? $localLang;
$sendSms = $sms->body($body, $templatePath, $variables, $aLang);
if (isset($parse[1])) $sendSms->addNumber($parse[0], $parse[1]);
else $sendSms->addNumber($parse[0]);
$sendSms = $sendSms->submit();
if ($sendSms) LogManager::Sms_Log(0, $reason, $sms->getTitle(), $sms->getBody(), implode(",", $sms->getNumbers()));
else $errors['sms'][$phone] = $sms->getError();
}
Tuzaklar
Birleşik biçim bunun tersidir, ülkeKodu|numara; kayıtlı kişi numara|ülkeKodu|dil olarak açılır. Yer değiştirmek makul görünen ama düşen bir numara üretir.
Mail alıcıları subject() içinde sıfırlar; SMS body() içinde. Sıfırlama olmazsa ikinci alıcı, içinde birinci alıcı da olan bir gönderim alır.
Müşteri paneli gönderimi fiyatlar, sürücünün $international özelliği true değilse reddeder, sonra bakiyeden düşer. Desteği yalnız config.php içinde iddia eden sürücü düşer.
Bildirim döngüsü try/catch içinde değildir ve yanlış değer dönen çağrıdan sonra getError() okur. Ayar controller'larınız fırlatabilir.
Bildirim dağıtıcısı body()'yi şablon adı vermeden çağırır, yani şablon adına bakan bir koşul hiç çalışmaz. Kod şablonunu çekirdek seçer ve use_otp() çağırır; sürücü yalnız kendi ayarını birleştirir.
SampleSMS her şeyi kabul eder ve her mesajı temp/sample-sms/ altına metin dosyası olarak yazar.
İ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.