Alan Yardımcıları

7 görüntülenme Markdown

İş kuralları yardımcılarda yaşar. Panel, müşteri paneli, API ve zamanlayıcı hepsi aynı kuralı çağırır. Bir hizmetin, bir siparişin ya da bir tutarın ne demek olduğu konusunda anlaşmalarının sebebi budur.

Genel Bakış

Model neyin saklandığını cevaplar. Yardımcı ne olması gerektiğini cevaplar. Bir hizmeti askıya almanın ne yaptığını, ödenen bir siparişin neye dönüştüğünü, bir tutarın para birimleri arasında nasıl çevrildiğini. Dört ekran da bu cevaplara ihtiyaç duyduğu için kural tek bir yerde yaşar ve her biri onu çağırır.

Hepsi WDB üzerine kurulu statik sınıflardır. Bir modül, bir kanca dinleyicisi ya da bir cron işleyicisi onlara bir controller ile aynı şekilde ulaşır. İşi sorgularla kendiniz yapmak, bugün doğru olan ama ürünün kendi kuralı ilk değiştiğinde ayrışan bir şey üretir.

Referans

Services Müşterinin sağlanmış hizmeti: satırı, eklentileri, durum geçişleri ve her geçişin taşıdığı modül aksiyonu.
Money Para birimleri, çevrim, gösterim ve vergi. Saklanan her tutar bir para birimine aittir; onu sunulan para birimine çeviren şey budur.
Orders Sipariş belgesi: oluşturma, kalemleri ve altındaki hizmetlerden aldığı durum.
Products Katalog: ürünler, kategoriler, eklentiler, fiyatlar, sunucular ve alan adı uzantıları; etkin dile çevrilmiş olarak.
User Müşteri kaydı, ona iliştirilen serbest bilgiler ve diğer ekranların gösterdiği aktivite kayıtları.

Services

Services
public static function get(int $id = 0, string $select = '', $noCache = false): array;
// -> users_products satırı: id, owner_id, order_id, invoice_id, subscription_id, type,
//    type_id, product_id, name, period, period_time, total_amount, amount, amount_cid, qty,
//    status, status_msg, suspended_reason, pmethod, auto_pay, cdate, duedate, suspend_date,
//    cancel_date, terminated_date, server_terminated, renewaldate, process_exemption_date,
//    module, options, metrics, notes, unread
//    'options' ve 'metrics' ÇÖZÜLMÜŞ dizi olarak gelir; NULL olan bir kolon null kalır.
//    'module' her zaman vardır ve "none"a düşer - var olmayan bir hizmetin yine de boş
//    olmayan bir dizi dönmesinin sebebi budur. $select kolonları daraltır, $noCache memoyu atlar.

public static function add(array $data = []): int;                      // yeni id, başarısızlıkta 0
public static function set(int $id = 0, array $data = []): bool;
public static function delete(int $id = 0, bool $cancelModule = false): bool;
public static function preload(array $ids = []): void;                  // tek sorgu, get()'in memosunu doldurur

public static function statuses(): array;
// -> durum anahtarı => ['title' => etiket, <grup> => true]. Anahtarlar waiting, inprocess,
//    active, completed, suspended, expired, cancelled; kodun dallanması gereken şey grup
//    bayrağıdır, çünkü 'completed' active, 'expired' ise cancelled grubuna girer.

public static function addons(string|int|null $service_id = 0): array;  // users_products_addons satırları,
                                                                        // artı hesaplanmış bir 'rak' sıralama kolonu
public static function get_addon(int $id = 0, string $select = ''): array;
public static function requirements(int $service_id = 0): array;

public static function change_status(int $serviceId, string $status, array $options = []): bool;
// $options, hepsi isteğe bağlı:
//   apply_on_module  false | true | 'sync' | 'queue'   modül aksiyonunu yerinde koştur ya da kuyruğa al
//   module_completed bool    modül işini zaten yaptı; hizmeti inprocess'te tutma
//   force_status     bool    durumu olduğu gibi yaz, aynı korumayı atla
//   reason           string  suspended ve cancelled için suspended_reason olarak saklanır
//   user_id          int     bunu kim yapıyor, geçmiş kaydı için
//   notify           bool    müşteriye durum bildirimini gönder

public static function run_module(array|int $service, string $action, array $params = []): mixed;
// -> modülde böyle bir metot yoksa null, modül reddettiyse false, aksi halde modülün kendi
//    dönüşü. Instance kurulamazsa ya da modül exception fırlattıysa fırlatır.

public static function add_history(int $user_id = 0, int $service_id = 0, string $name = '', array $data = []): int;

Money

Money
public static function getUCID(): int;      // bu ziyaretçiye sunulan para birimi id'si
public static function selected(): int;    // getUCID()'nin okunur takma adı

public static function exChange($amount, $cid1 = 0, $cid2 = 0);
// -> çevrilmiş tutar. İki cevap çevrim değildir:
//    $cid1 === $cid2  -> $amount olduğu gibi döner, hiçbir kur okunmaz
//    çeviremiyorsa    -> 0; bilinmeyen para birimi, 0 olan bir kur ve sıfırdan büyük
//                        olmayan bir $amount hepsi buraya düşer

public static function formatter($amount = 0, $cid = 0, $symbol = false, $exchange = false, $info = false): array|string;
// -> "99.90" · $symbol ile: "$99.90" · $info ile dize yerine bir dizi:
//    ['currency_id' => 4, 'currency_code' => 'USD', 'prefix' => '$', 'suffix' => '',
//     'symbol' => '$', 'amount' => '99.90']
//    $exchange önce çevirir: true sunulan para birimini, bir id ya da kod onu kullanır.

public static function formatter_symbol($amount = 0, $currency = 0, $exchange = false, $info = false): string;
// Burada üçüncü argüman $exchange'dir, $symbol DEĞİL - sembol zaten hep açıktır.

public static function deformatter($amount = '', $currency = 0): float;   // "1.234,56" -> 1234.56

public static function Currency($identified = 0, $isActive = false): array;
// -> currencies satırı: id, status, local, hidden, country, countries, code, name, prefix,
//    suffix, rate, format, modules. Böyle bir para birimi yoksa []. $identified bir id ya da
//    bir kod ("USD") alır; $isActive pasif bir para birimine de [] dedirtir.

public static function getCurrencies(int $default = 0): array;
public static function currency_code(int $id = 0): string;
public static function getSymbol($currency = 0);
// -> ['position' => 'LEFT'|'RIGHT', 'prefix' => ..., 'suffix' => ..., 'symbol' => ...]

public static function get_tax_amount($amount = 0, $rate = 0);            // $amount'un ÜSTÜNE eklenen vergi
public static function get_inclusive_tax_amount($amount = 0, $rate = 0);  // $amount'un İÇİNDEKİ vergi
public static function get_discount_amount($amount = 0, $rate = 0);       // $amount * $rate / 100

Orders

Orders
public static function get(int $id, $select = ''): array;
// -> orders satırı: id, user_id, invoice_id, affiliate_id, ordernum, cdate, tax_type,
//    taxes, amount, currency, pmethod, status, ip, notes, discounts, items, details
//    taxes, discounts, items ve details ÇÖZÜLMÜŞ dizi olarak gelir. Sipariş yoksa [].
public static function get_order_by_number(int $num, string $select = ''): array;

public static function create(array $data = []): int;
// Yalnız bu anahtarlar okunur; $data içindeki başka her şey saklanmaz, düşürülür.
//   user_id       int     ZORUNLU
//   amount        float   ZORUNLU - 0.0 olabilir, eksik olamaz
//   currency      int     ZORUNLU - bir para birimi id'si
//   status        string  'waiting'
//   pmethod       string  'none'
//   tax_type      string  'exclusive'
//   taxes         array   JSON'a çevrilir
//   discounts     array   JSON'a çevrilir
//   items         array   JSON'a çevrilir
//   details       array   JSON'a çevrilir
//   invoice_id    int     0
//   affiliate_id  int     0
//   notes         string  null
//   ip            string  isteği yapanın adresi
// Zorunlu bir anahtar eksikse exception fırlatır. Sipariş numarası sizin için üretilir ve
// bir dinleyici çağrının tamamını veto edebilir.

public static function set(int $id, array $data): bool;
public static function delete(int $id, bool $deleteServices = true): bool;
public static function services(int $order_id = 0): array;
// -> siparişin hizmetleri; id, name, type, status, amount, module, period, period_time ile daraltılmış

public static function statuses(): array;          // waiting, inprocess, active, cancelled
public static function payment_statuses(): array;  // incomplete, complete, unknown
public static function change_status(int $order_id, string $status, bool $updateServices = false, string|bool $applyOnModule = false): bool;
public static function recalculateStatus(int $order_id, bool $force = false): ?string;
public static function generateOrderNumber(): int;
public static function add_history($user_id = 0, $order_id = 0, $name = '', $data = []): int;

Products

Products
public static function get(string|int|null $id = 0, string $lang = '', string $select = ''): array;
// -> products satırı, artı çevrilmiş 'title' ve onun takma adı 'name'. Boş bir $lang etkin
//    dil demektir. 'options' ve 'module_data' ÇÖZÜLMÜŞ dizi olarak gelir. Böyle bir ürün
//    yoksa []. Süreç boyunca (id, lang) başına memolanır; yani arada düzenlenen bir satır
//    yeniden okunmaz.
public static function set($id = 0, $set = []): bool;

public static function types(): array;
// -> tip anahtarı => ['title' => ..., 'description' => ..., 'icon' => ...]. Liste sabit
//    değildir: bir modül onu register:product_types kancasıyla genişletir.
public static function groups(): array;
public static function cycles(): array;
public static function cycle($duration = '', $period = ''): string;      // (1, 'month') -> "monthly"

public static function get_price($type, $owner, $owner_id, $lang = 'none'): array;
public static function get_price_by_criteria(string $owner, int $owner_id, string $cycle = '', string|int $currency = '', int $status = 1, string $type = ''): array;
// $owner tabloya göre değişen ve TAHMİN EDİLEMEYEN bir sabittir: ürün fiyatı 'products'
// (çoğul), alan adı uzantısı 'tld', eklenti 'addon' altında saklanır. Yanlış biçim hiçbir
// şeyle eşleşmez ve hiçbir hata bildirmez.

public static function addon($id = 0, $lang = '', $select = ''): array;
public static function requirement($id = 0, $lang = '', $select = '');
public static function get_category($id, $lang = '', $select = ''): array;
public static function get_server($id = 0): array;     // servers satırı, 'password' çözülmüş olarak
public static function get_tld($definition = 'com', $select = '');

User

User
public static function getData($id = 0, $fields = '*', $fetch = 'object', $noCache = false): object|array;
// $fields kabul edilir ama KULLANILMAZ: users satırının tamamı her zaman okunur ve memo
// yalnız id ile anahtarlanır. Biçimi $fetch seçer - 'object' (varsayılan) bir stdClass,
// başka her değer bir dizi verir. Dolayısıyla tek kolon okumak bunu açıkça söylemelidir:
//   $groupId = (int) (User::getData($id, '', 'array')['group_id'] ?? 0);

public static function setData($id = 0, $data = []): int|bool;
public static function create($data = []);
public static function delete(int $id, array $options = []): bool;

public static function getInfo($owner_id = 0, $names = [], $noCache = false): array;
// -> istediğiniz adlar ad => değer olarak; hiç saklanmamış olan için null.
public static function AddInfo($owner_id = 0, $values = []);       // upsert, ad => değer
public static function deleteInfo($owner_id = 0, $name = ''): int|bool;

public static function addAction($id = 0, $reason = '', $detail = '', $data = [], $target_id = 0);
// $id         kaydın ait olduğu müşteri
// $reason     serbest biçimli gruplama etiketi: 'alteration', 'addition', 'delete', 'module-log'
// $detail     locale actions.php içindeki ÇEVİRİ ANAHTARI - cümle bundan üretilir
// $data       o cümlenin kullandığı yer tutucular ({service_name} vb.); ayrıca JSON olarak saklanır
// $target_id  kaydın konusu olan kayıt, müşterinin kendisi değilse

public static function addNote(int $owner_id, string $content, bool $pinned, int $adminId, string $adminName): array|false;
public static function getPrivileges($id = 0, $resultType = 'array'): array|string;
public static function parseDealership(string $data): array;

"Bulunamadı" Neye Benzer

Çağrı Var olmayan kayıt için cevap Yazılacak guard
Services::get($id) ['module' => 'none'] - boş değil, yani doğruluk testinden geçer if (!($service['id'] ?? 0))
Services::get_addon($id) [] if (!$addon)
Orders::get($id) [] if (!$order)
Products::get($id) [] if (!$product)
Money::Currency($id) [] if (!$currency)
User::getData($id) boş bir stdClass, 'array' ile [] if (!($user->id ?? 0))

Örnek

kuralları yeniden yazmak yerine kullanmak
// Hizmet. "Bulunamadı" cevabı yine de doğru sayılan tek getter budur; bu yüzden guard
// diziye değil kimliğe bakar.
$service = Services::get($id);
if (!($service['id'] ?? 0)) throw new Exception('Hizmet bulunamadı');

// Tutar, yanında saklanan para birimine aittir ve ziyaretçiye başka biri sunuluyor olabilir.
// Önce çevirin, sonra biçimlendirin.
$served    = Money::getUCID();
$amount    = Money::exChange((float) $service['amount'], (int) $service['amount_cid'], $served);
$displayed = Money::formatter_symbol($amount, $served);

// İşlemi yardımcı üzerinden yapın; böylece geçmiş kaydı, modül ve bildirim panelin
// yapacağı gibi gerçekleşir.
Services::change_status((int) $service['id'], 'suspended', [
    'apply_on_module' => 'queue',
    'reason'          => 'Ödeme gecikti',
    'user_id'         => $adminId,
    'notify'          => true,
]);

// Müşterinin aktivitesine yazın. Üçüncü argüman locale actions.php içindeki anahtardır;
// dördüncüsü o cümlenin yer tutucularını doldurur.
User::addAction((int) $service['owner_id'], 'alteration', 'acme-service-suspended', [
    'service_id'   => (int) $service['id'],
    'service_name' => $service['name'] ?? '',
    'amount'       => $displayed,
], (int) $service['id']);
bunu geri okuyan taraf
// Kayıt hem anahtarı, hem kurulumun kendi dilinde üretilmiş cümleyi, hem de yer tutucuları
// JSON olarak tutar. Çevirisi olmayan bir anahtar burada anahtarın kendisi olarak görünür.
$stmt = WDB::select('reason, detail, locale_detail, data, ctime')
    ->from('users_actions')
    ->where('owner_id', '=', (int) $service['owner_id'])
    ->where('detail', '=', 'acme-service-suspended')
    ->order_by('id DESC')
    ->limit(1);

$entry = $stmt->build() ? $stmt->getAssoc() : [];
$vars  = $entry ? Utility::jdecode($entry['data'] ?? '', true) : [];

// Ve yardımcının gerçekten yazdığı durum; ilk çağrının doldurduğu memoyu atlayarak.
$after = Services::get((int) $service['id'], '', true)['status'] ?? '';

Tuzaklar

Bir satır yazmak, işlemi yapmakla aynı şey değildir

Bir hizmeti yardımcı üzerinden oluşturmak ya da askıya almak, çevresindeki şeyleri de yapar. Geçmiş kaydını, ilişkili kayıtları, modül aksiyonunu, başka kodun dinlediği olayları. Kendi yazdığınız bir insert ya da update bunların hiçbirini yapmaz ve doğru görünen ama sonradan tuhaf davranan bir kurulum bırakır.

Yapılamayan bir çevrim girdiyi değil sıfırı döndürür

Saklanan her tutar bir para birimine aittir ve ziyaretçiye başkası sunuluyor olabilir. Karşılaştırmadan, toplamadan ya da göstermeden önce çevirin. Cache'lediğiniz her şeyin anahtarına sunulan para birimini koyun. Ancak çevrim yapılamadığında exChange() 0 döner. Bilinmeyen bir para birimi, sıfır olan bir kur ve sıfırdan büyük olmayan bir tutar hepsi oraya düşer. Negatif sayı olarak geçirilen bir alacak ya da iade, tek kelime etmeden sıfıra iner.

Göründüğünden başka bir şey cevaplayan iki getter

Services::get() her zaman bir module anahtarı taşır; yani var olmayan bir hizmet doğru sayılan bir dizidir ve if (!$service) hiçbir zaman tetiklenmez. User::getData() kolon listesini tümüyle yok sayar ve dizi istemediğiniz sürece bir stdClass verir. Tek kolon beklerken sonucu cast etmek sessizce yanlış sayıyı üretir. Money::formatter_symbol()'da ise üçüncü argüman $symbol değil $exchange'dir ve dördüncüsü, alttaki çağrıyı beyan edilen string dönüş tipine karşı bir dizi döndürmeye zorlar.

Bir aktivite kaydı çeviri anahtarını ister

Cümle, metin olarak geçtiğiniz bir şeyden değil üçüncü argümandan üretilir; ikincisi yalnızca bir gruplama etiketidir. Bir dil dosyasında olup diğerlerinde olmayan bir anahtar, geri kalan herkes için müşterinin geçmişinde çıplak anahtar olarak görünür. Çağrıyı eklerken anahtarı tüm dil dosyalarına ekleyin.

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.