# Bildirim Şablonu Değişkenleri

https://dev.wisecp.com/tr/bildirim-sablonu-degiskenleri

Bir bildirim şablonunun basabileceği her şey, her adın üç katmandan hangisinden geldiği ve hangilerinin sizin verdiğiniz değeri sessizce ezdiği.

## Genel Bakış

Şablona tek bir düz ad kümesi ulaşır. Bu küme üç kaynaktan sabit bir sırayla kurulur. Bir adın hangi kaynaktan geldiğini bilmek, pratikte sorulan iki soruyu yanıtlar: bir yer tutucu neden boş çıktı ve geçtiğiniz değer neden yok sayıldı.

- **kurulum katmanı**: Logolar, renkler, şirket bilgileri, iletişim bağlantıları, içinde bulunulan yıl. Olay istesin istemesin her olayın her şablonuna eklenir.
- **alıcı katmanı**: Mesajın kendisi için üretildiği hesap. Yalnızca üretim çağrısına bir müşteri kimliği ulaştığında vardır; aynı adın bir akışta dolu, başka bir akışta boş olmasının sebebi budur.
- **olay katmanı**: Grubun çözümleyicisinin varlıktan kurduğu küme, artı çözümleyicinin o olaya özgü kaydının eklediği her şey. Bir olay eklediğinizde genişlettiğiniz katman budur.

## Yapı

### Kurulum Sırası

Önce olay katmanı kurulur, diğer ikisi altına değil **üstüne** serilir. Bu makaledeki neredeyse her sürprizin kaynağı budur.

```bash
çözümleyici          varlık -> olayın değişkenleri            (sizinkiler)
      ↓
View::notifications  template_name ve template_type ekler
      ↓
variables_handler    alıcı bloğunu ekler  (yalnız müşteri kimliği > 0)
                     kurulum bloğunu ekler  (her zaman)
      ↓                 ^ ikisi de var olanı EZER, dört istisna dışında
motor                gövdeyi birleşmiş kümeyle render eder
      ↓
                     render edilmiş gövde notifi_body olur
      ↓
motor                kabuğu, sonra konuyu aynı kümeyle render eder
```

- **dört ad size teslim olur**: Alıcının görünen adları yalnızca çözümleyici onları zaten set etmediyse doldurulur: tam ad, ad, soyad ve hitap adı. İki platform katmanındaki diğer her ad koşulsuz yazılır.
- **müşteri kimliği yoksa alıcı bloğu da yok**: Üretim sıfır müşteri kimliğiyle çağrıldığında alıcı katmanının tamamı atlanır. Hesap olmayan bir adrese yönelen bir mesajda o adların hepsi boş kalır.
- **gövde de bir değişkendir**: Biten olay gövdesi bir değişken olarak atanır ve kabuk onu gösterir. O ad yalnız kabuk dosyalarında anlamlıdır. Bir olay gövdesinin içinde yazmak hiçbir şey vermez, çünkü henüz yoktur.

### Bildirilen ile Enjekte Edilen

İki liste vardır ve aynı liste değildirler. Biri operatörün şablonu düzenlerken gördüğü rozetleri besler; diğeri gerçekten ulaşan şeydir. İkisi de bir filtre değildir: her ikisinde de olmayan bir ad, çözümleyici onu set ettiyse yine görünür.

| Liste | Kuran | Ne için | Render anındaki etkisi |
| --- | --- | --- | --- |
| platform kümeleri | `Notification::variables()` | düzenleyicinin rozet listesi | yok |
| grup temel kümesi | `Notification::group_variables()` | düzenleyicinin rozet listesi | yok |
| kaydın kendi listesi | yapılandırma kaydındaki `variables` anahtarı | düzenleyicinin rozet listesi | yok |
| gerçekten enjekte edilen | çözümleyici, sonra üretim çağrısı | mesajın üretimi | her şey |

İlk üçü mekanizma değil belge olduğu için kayarlar. Gelen koda karşı ölçüldü: alıcı kümesi on yedi ad bildirir ama on dokuz ad enjekte edilir. Kurulum kümesi de üretim çağrısının ayrıca eklediği bir adı bildirir. Boşluklar aşağıdaki tablolarda işaretli.

## Referans

### İmzalar

```php
// coremio/helpers/notification.php
// $type 'system' | 'user' olur. Başka bir değerde $variables süslü parantezleri
// soyulmuş olarak döner; yapılandırma kaydının CSV'si rozet listesine böyle çevrilir.
public static function variables(string $type = '', array $variables = []): array;

// Düzenleyicinin gösterdiği grup temel kümesi: 'invoice' | 'order' | 'service' |
// 'domain' | 'user-tickets' | 'admin-tickets'. Diğer her grup boş dizi döner.
public static function group_variables(string $group = ''): array;

// coremio/classes/View.php
public static function notifications($type = 'mail', $template_name = '', $content = '',
                                     $variables = [], $lang = '', $user = 0): array;

// İki platform katmanını $variables üzerine birleştirir, sonra $str'yi YERİNDE
// render eder. $str referanslıdır: hem şablon kaynağı hem de sonuçtur.
public static function variables_handler($type, $user_id = 0, $variables = [], &$str = '', $lang = ''): void;

// coremio/classes/TemplateEngine.php
// $engine 'smarty' | 'twig' | 'none' olur. Her derleme hatasında ORİJİNAL dizeyi
// döner, yani bir başarısızlık hiçbir şey yapmamış bir şablon gibi görünür.
public static function render_notification($engine, $content, $variables = []): string;
```

- **Notification::variables()**: İki platform kümesini ad olarak verir. Başka bir argümanla, bir listenin süslü parantezlerini soyan küçük bir yardımcıya dönüşür; yapılandırma kaydının virgüllü değerinin rozete çevrilme yolu budur.
- **Notification::group_variables()**: Grubun temel kümesini ad olarak verir. Temel kümesi olmayan grubun yanıtı hata değil boş dizidir. Böyle bir grup, bozuk bir düzenleyici değil kısa bir rozet listesi gösterir.
- **View::notifications()**: Dosyaları okur, katmanları birleştirir, gövdeyi, kabuğu ve konuyu üretir. Bu makaledeki her şey ona yapılan tek bir çağrının içinde olur.
- **View::variables_handler()**: İki platform katmanının gerçekten yazıldığı ve ezme kuralının yaşadığı yer. Referanslı argümanı üzerinden yerinde çalışır ve hiçbir şey döndürmez.
- **filter:notification.render_variables**: Alıcı başına bir kez, o alıcının gövdesi üretilmeden hemen önce çalışır. Bir çözümleyiciye dokunmadan ad eklemenin yolu ve değeri alıcıya göre değiştirebilen tek yol. Değişken kümesi referansla gelir; üzerine yazın, dönüş değeri kullanılmaz.
- **filter:notification.template_merge_fields**: Yalnız düzenleyici zamanı. Operatörün düzenleme sırasında gördüğü rozet listesine bir ad ekler ve mesajın kendisine hiçbir etkisi yoktur. Liste de referansla gelir; ona ekleyin, dönüş değeri yok sayılır.

### Kurulum Katmanı

Yirmi iki ad bildirilir ve hepsi her mesajda enjekte edilir. Bir tane de üretim çağrısının eklediği ve hiç bildirilmeyen ad vardır.

| Ad | Taşıdığı | Bilinmesi gereken |
| --- | --- | --- |
| `website_url` | Kurulum adresi. | Kurulum güvenli şemayı zorunlu kıldığında yeniden yazılır. |
| `website_domain` | Şemasız, yalnız host. | Metin içindir, bağlantı kurmak için değil. |
| `website_title` | Mesaj dilinde site başlığı. | Şirket bilgilerinden değil, website çevirilerinden gelir. |
| `company_name` | Yasal ad. | Set edilmemişse bilgi bloğunun ilk satırına düşer. |
| `website_infos` | Çok satırlı bilgi bloğu. | E-postada satır sonları işaretlemeye çevrilir, kısa mesajda olduğu gibi bırakılır. |
| `website_address` | Dile göre posta adresi. | Dile özgü adres genel olanı ezer. |
| `website_emails` | Tek dizede birleştirilmiş açık adresler. | Liste değil dizedir: döngüye sokulamaz. |
| `website_phones` | Tek dizede birleştirilmiş açık numaralar. | Yukarıdaki adreslerle aynı biçim. |
| `website_contact_url` | Mesaj dilinde iletişim sayfası. | Alıcıya göre yerelleşir, yani tek dispatch'in iki satırında farklı olur. |
| `support_link` | Talep oluşturma sayfası. | Yazmadan önce aşağıdaki işaretle eşleyin. |
| `is_enable_support` | Talep sisteminin açık olup olmadığı. | Koşul için bir boolean. Gelen footer tüm iletişim bloğunu bunun arkasına gizler. |
| `website_header_logo` | Sitenin açık logosu. | Mutlak adres. |
| `website_footer_logo` | Sitenin koyu logosu. | Mutlak adres. |
| `notifi_header_logo` | E-postaya özel logo. | Site logosuna düşer; vektör dosya varsa raster karşılığıyla değiştirilir, çünkü e-posta istemcileri vektör çizemez. |
| `notifi_footer_logo` | E-postaya özel koyu logo. | Aynı geri düşme ve aynı değiştirme. |
| `theme_color1` | Birincil renk. | Baştaki işaretçi olmadan yalnız rakamlar: işaretçiyi şablon kendisi yazar. |
| `theme_color2` | İkincil renk. | Aynı biçim. |
| `theme_text_color` | Gövde metni rengi. | Aynı biçim. |
| `social_links` | Sosyal profil listesi. | Satır listesi, aşağıdaki biçimlere bakın. Hiçbiri yapılandırılmamışsa boştur, döngüyü koruyun. |
| `current_year` | Dört haneli yıl. | Telif satırı için; hiç bayatlamaz. |
| `template_name` | Olay, `grup/ad` biçiminde. | Üretim çağrısının kendisi set eder. |
| `notifi_body` | Biten olay gövdesi. | Burada bildirilir ama yalnız gövde üretildikten sonra var olur. Kabukta kullanılır, olay gövdesinde boştur. |
| `template_type` | Kanal: e-posta ya da kısa mesaj. | **Enjekte edilir ama bildirilmez**, yani düzenleyicinin rozet listesinde hiç görünmez. Paylaşılan bir parçanın kanala göre dallanmasını sağlar. |

### Alıcı Katmanı

Yalnızca üretime bir müşteri kimliği verildiğinde vardır. On yedi ad bildirilir; iki tanesi daha bildirilmeden enjekte edilir.

| Ad | Taşıdığı | Bilinmesi gereken |
| --- | --- | --- |
| `user_greeting_name` | Varsa şirket adı, yoksa tam ad. | Bir mesaja başlamak için doğru olan. **Teslim olur**: zaten set etmiş bir çözümleyici kazanır. |
| `user_full_name` | Ad ve soyad. | Çözümleyiciye **teslim olur**. |
| `user_name` | Ad. | Çözümleyiciye **teslim olur**. |
| `user_surname` | Soyad. | Çözümleyiciye **teslim olur**. |
| `user_company_name` | Şirket adı, bireysel hesapta boş. | Koşulsuz ezilir. |
| `user_email` | Hesabın adresi. | Hesaptaki adres; bu kopyanın gittiği adres olmak zorunda değil. |
| `user_phone` | Telefon, varsa ön ekli. | Hesapta yoksa boş değil null olur. |
| `user_id` | Hesap kimliği. | Referans satırında işe yarar, tek başına müşteri için anlamsızdır. |
| `user_group` | Müşteri grubu adı. | Hesap hiçbir grupta değilse boştur. |
| `user_country` | Birincil adresten ülke adı. | Kayıtlı adres yoksa null. |
| `user_city` | Şehir. | Aynı kaynak, aynı uyarı. |
| `user_state` | İl ya da eyalet. | Aynı kaynak, aynı uyarı. |
| `user_address` | Açık adres. | Aynı kaynak, aynı uyarı. |
| `user_zipcode` | Posta kodu. | Aynı kaynak, aynı uyarı. |
| `user_ip` | Hesapta kayıtlı adres. | Kayıt anındaki adres, bu mesajı tetikleyen şeyin adresi değil. |
| `user_login_link` | Mesaj dilinde giriş sayfası. | Alıcıya göre yerelleşir. |
| `user` | Hesap satırının tamamı ve adresi. | Bir koleksiyon, aşağıdaki biçimlere bakın. Önce adlandırılmış değişkene uzanın. |
| `admin_login_link` | Panel giriş sayfası. | **Enjekte edilir ama bildirilmez.** Personel kopyaları içindir; müşteriye giden bir gövdede basmayın. |
| `user_pass` | Beş yıldız. | **Enjekte edilir ama bildirilmez** ve bir değer değil maskedir. Onu basan eski bir şablonun boşluk yerine maske göstermesi için vardır. |

### Olay Katmanı, Gruba Göre

Grubun çözümleyicisinin, olay adına bakmadan önce kurduğu küme. Yalnız altı grup temel küme bildirir; geri kalanlar kümelerini tümüyle olayın kendi kaydında kurar.

- **invoice**: `invoice, invoice_idn, invoice_payment_link, invoice_subtotal, invoice_total, invoice_tax_rate, invoice_tax, invoice_date_created, invoice_date_due, invoice_date_paid, invoice_date_taxed, invoice_payment_method, invoice_remaining_day, invoice_delayed_day, invoice_refund_date, invoice_cancelled_date, legal_invoice_download_link, items`. Tutarlar para birimi sembolüyle zaten biçimlenmiş gelir, yeniden biçimlemeyin. Son dördü yalnız kendi olaylarında set edilir. İndirimler `invoice_discount_total`, `invoice_has_discount` ve `invoice_discounts` ile gelir: her indirim için `type`, `label`, `amount` ve `amountF` taşıyan bir satır; etiket çevrilmiş gelir.
- **order**: `order, order_id, order_number, order_name, order_amount, order_currency, order_payment_method, order_status, order_detail_link, order_date_created, order_date_start, order_date_end, order_period, order_period_unit, order_group_name, order_category_name, order_services_summary, items`. Kalem koleksiyonunun biçimi faturanınkinden farklıdır: satın alınan ürün başına bir satır ve içinde iç içe eklentileri.
- **service**: `service, service_id, service_order_id, service_name, service_type, service_module, service_subscription_identifier, service_period, service_period_unit, service_period_time, service_cycle, service_amount, service_date_created, service_date_start, service_date_end, service_detail_link, service_group_name, service_category_name, service_domain, service_ip, service_requirements, service_addons, service_server_ip, service_server_hostname, service_server_port, service_ns1, service_ns2, service_ns3, service_ns4, service_username, service_password, service_assigned_ips`. Son gruptaki adlar canlı erişim bilgileridir; çözülmüş bir parola da dahil, tuzaklara bakın.
- **domain**: Yukarıdaki hizmet kümesinin tamamı, artı `domain, day, grace_days, redemption_days, redemption_fee, days_past_due, domain_transfer_code, reason`. Alan adı bir hizmettir, yani şablonları herhangi bir hizmet adını da basabilir.
- **user-tickets ve admin-tickets**: `ticket, ticket_id, ticket_num, ticket_link, ticket_subject, ticket_department, ticket_service, ticket_status, ticket_priority, ticket_admin_name, ticket_date, ticket_last_reply_date, ticket_assigned_by_admin, user_last_message, admin_last_message, user_reply, admin_reply`, artı talep bir hizmete bağlıysa hizmet kümesinin tamamı. Bağlantı gruba göre değişir: personel kümesi panele, müşteri kümesi portala gider.
- **user, admin-messages, sms-intl**: Hiç temel küme yok. Her olayın kaydı şablonunun tam olarak ihtiyaç duyduğunu kurar; aynı gruptaki iki olayın neredeyse hiç ad paylaşmamasının sebebi budur.

### Koleksiyonlar ve Anahtarları

Adların dördü dize değildir. Birini doğrudan yazmak işe yarar bir şey vermez; bunlar bir döngü ya da anahtarlı okuma içindir.

| Ad | Biçim | Her satırdaki anahtarlar |
| --- | --- | --- |
| `items` (fatura) | fatura kalemi başına bir satır | `id, owner_id, user_id, user_pid, description, quantity, amount, total_amount, currency, rank, amountF, service_id, service_domain, service_ip, service_group_name, service_category_name`. Yenileme kalemi ayrıca `service_type, service_old_duedate, service_new_duedate` taşır. |
| `social_links` | satır listesi | `name, url, icon`. Gelen kabuk görsel dosya adını küçük harfe çevrilmiş addan kurar. |
| `user` | tek satır | Hesap kolonları, artı birincil adresi taşıyan `address`. Basmaya değer her alanın zaten adlandırılmış bir değişkeni var. |
| `service_addons` ve `service_requirements` | satır listeleri | Saklandıkları haliyle satırlar, biçimlenmemiş. Şablonun gerçekten kalem kalem listelemesi gerektiğinde döngüye sokun; arkalarında hazır bir biçimleme yok. |

Fatura kalemi satırlarında biçimlenmiş tutar büyük F ile biter: çıplak anahtar ham sayıdır, F ile biten ise yazılacak dizedir. Bu ikiliyi ters kullanmak, üzerinde para birimi olmayan biçimlenmemiş bir rakam gösterir.

### Olay Başına Ekler

Temel kümenin ötesinde, çözümleyicinin kaydı yalnız o olayın ihtiyaç duyduğunu ekler. Temsili bir örneklem ve her biri için çağıranın geçmesi gerekenler.

| Olay | Eklediği | Besleyen bağlam anahtarı |
| --- | --- | --- |
| `user/two-factor-verification` | `code` | `code` |
| `user/email-activation` | `activation_code, activation_link` | `code`, `activation_link`, mesajı yönlendirmek için isteğe bağlı `to_email` |
| `user/email-changed` | `old_email, new_email` artı cihaz bloğu | `old`, `new`, isteğe bağlı `to_email` |
| `user/password-changed` | `reset_password_link` artı cihaz bloğu | `reset_link` |
| `invoice/invoice-reminder` | `invoice_remaining_day` | `remaining_day` |
| `invoice/invoice-overdue` | `invoice_delayed_day` | `delayed_day` |
| `invoice/invoice-auto-payment-failed` | `error_message, card_ln4` | `error_message`, `card_ln4` |
| `admin-messages/backup-completed` | çağıran ne kurduysa | `variables`, olduğu gibi iletilir |

Yukarıda geçen cihaz bloğu, güvenlik olaylarına eklenen küçük ve sabit bir kümedir: `browser`, `platform`, `ip`, `location_country`, `location_city` ve `date`. İki konum adı yer tutucudur ve her zaman boştur, yani onları basan bir şablon hiçbir şey basmaz.

## Örnek

Tek bir parçada üç katman, ardından kendi adınızı eklemenin desteklenen iki yolu.

```smarty
{* alıcı katmanı *}
Sayın {$user_greeting_name},

{* olay katmanı: para birimiyle zaten biçimlenmiş, olduğu gibi basılır *}
{$invoice_idn} numaralı {$invoice_total} tutarındaki faturanızın son ödeme tarihi {$invoice_date_due}.

{* olay katmanı, koleksiyon: amountF biçimli dize, amount ham sayı *}
{foreach from=$items item=item}
- {$item.description} {$item.amountF}
  {if $item.service_domain != ""}({$item.service_domain}){/if}
{/foreach}

{* kurulum katmanı, liste boş olabildiği için korumalı *}
{if $is_enable_support}Sorularınız için: {$support_link}{/if}
{$company_name} {$current_year}
```

```php
// coremio/helpers/notification.php, grubun çözümleyicisinin içinde.
// Bir platform adını yeniden kullanmayın: user_email ve website_url bundan sonra
// yazılır ve oraya koyduğunuz her şeyi ezer.
switch ($name) {
    case 'acme-quota-reached':
        $variables['quota_percent'] = (int) ($context['percent'] ?? 0);
        $variables['quota_limit']   = Money::formatter_symbol(
            (float) ($context['limit'] ?? 0),
            (int) ($service['amount_cid'] ?? 0),
        );
        break;
}
```

```php
// Alıcı başına bir kez, o alıcının gövdesi render edilmeden hemen önce koşar; yani
// değeri alıcıya göre de değiştirebilir. İlk argüman referanslıdır.
Hook::add('filter:notification.render_variables', 1, function (&$variables, $group, $name, $recipient) {
    if ($group !== 'service') return;

    $variables['acme_portal_link'] = 'https://portal.example.com/s/' . (int) ($variables['service_id'] ?? 0);
});

// Yalnız düzenleyici: adı operatörün düzenleme sırasında gördüğü rozet listesine koyar.
// Render anında hiçbir şeyi değiştirmez, yani hem keşfedilebilir hem basılabilir olması
// gereken bir ad için iki dinleyici de gerekir.
Hook::add('filter:notification.template_merge_fields', 1, function (&$fields, $group, $name) {
    if ($group === 'service') $fields[] = 'acme_portal_link';
});
```

## Tuzaklar

> **Bu adlardan biri çalışan bir paroladır**
> 
> Hizmet kümesi saklanan kimlik bilgisini çözülmüş halde, sunucu adresinin, portun ve kullanıcı adının yanında taşır. Onu basmak canlı bir girişi bir gelen kutusuna ve mesaj loguna kalıcı olarak koyar. Bunun yerine hizmet sayfasına bağlantı verin ve kimlik bilgisini tüm amacı onu iletmek olan tek mesaja saklayın.

> **Bir platform adını yeniden kullanmak değerinizi kaybettirir**
> 
> İki platform katmanı da çözümleyicinin kümesinin üzerine serilir ve yalnız dört alıcı görünen adı var olana teslim olur. Bir adresi, bağlantıyı ya da rengi platform adıyla set ederseniz şablon onu görmeden ezilir ve hiçbir şey loglanmaz.

> **Var olmayan ad hiçbir şey göstermez**
> 
> Ne uyarı ne de çıktıda bir işaret olur, yani yanlış yazılmış bir yer tutucu tam olarak boş kalmış bir değer gibi görünür. Bir mesajdan bir satır kaybolduğunda, çözümleyiciye bakmadan önce yazımı buradaki tablolara karşı kontrol edin.

> **Bildirilen liste belgedir, sözleşme değil**
> 
> Operatörün gördüğü rozet listesi, hiçbir şeyin çözümleyiciye karşı doğrulamadığı üç statik bildirimden kurulur. Bir ad listede olmadan görünebilir, listede olup hiç ulaşmayabilir de. Çözümleyicinin set ettiğine güvenin ve operatörün de güvenebilmesi için bildirimleri güncelleyin.

## İlgili Makaleler

- [Bildirim Şablonları Nasıl Çalışır](https://dev.wisecp.com/tr/bildirim-sablonlari-nasil-calisir)
- [E-posta Şablonu Yazma](https://dev.wisecp.com/tr/e-posta-sablonu-yazma)
- [SMS Şablonu Yazma](https://dev.wisecp.com/tr/sms-sablonu-yazma)
- [Kanca Dinleyicisi Yazma](https://dev.wisecp.com/tr/kanca-dinleyicisi-yazma)
- [Alan Yardımcıları](https://dev.wisecp.com/tr/alan-yardimcilari)
