Özel Alan Ekleme

1.7k görüntülenme Markdown

Bir müşteriye ya da talebe kolon eklemeden ek bilgi iliştirin.

Genel Bakış

"Özel alan" adını iki motor paylaşır. Müşteri profili alanları users_custom_fields içinde dil başına tanımlanır, değerleri anahtar/değer satırlarıdır. Talep alanları tickets_custom_fields içinde iki eksene bağlanır.

İkisinde de şema değişikliği gerekmez: bir tanım satırı eklersiniz, değer genel bir depoya düşer.

Ön Koşullar

  • Tanım ekranlarına erişen bir operatör hesabı ya da ayarlar ve talepler kapsamlı bir jeton.
  • Kanca mekanizmasına aşinalık; dönüşüm iki filtre kancasıyla yapılır.
  • Kurulu dil kodları: tanım dil başına bir satırdır, yani iki dil iki id demektir.

Yapı

Tanım ile değer ayrıdır; değer satırının adı field_ ile tanım id'sinin birleşimidir.

TabloNe tutarAnahtarı
users_custom_fieldsDil, tip, etiket, seçenekler, işaretler, sıraid, dil başına bir satır
users_informationsDeğer, metin olarakowner_id ve field_{id}
tickets_custom_fieldsTalep alanı ve departmanıid; etiket ve tip _lang ikizinde
tickets_access_groupsYanıt tarafındaki gruplama ve alan id'leriid; ilişki grupta durur

Depo tipsiz metindir: çok seçimli alan virgülle birleşir, boş cevap eksik satır değil boş dizedir.

Adım Adım

Alanı Tanımlayın

  1. Tanımı dil başına bir kez oluşturun: Ayarlar altındaki müşteri alanları listesi ya da API kaynağı.
  2. Tipi seçin: text, textarea, select, checkbox, radio; seçim tiplerinde options virgüllü liste alır.
  3. Görünürlük işaretlerini ayarlayın; bağımsız mantıksal değerlerdir ve birlikte çalışırlar.
  4. Satıra verilen id'yi not edin; kodunuz etiketi değil id'yi kullanır.

Değeri Okuyun ve Yazın

  1. Bilgi yardımcısıyla, field_{id} anahtarlarıyla yazın.
  2. Bilgi okuyucusuyla okuyun: satırı olmayan ad eksik anahtar olarak değil null olarak döner.
  3. Okuyucu istek boyunca hafızaya alır; yazdıktan sonra üçüncü argümanla atlayın.
  4. "Cevaplanmadı" anlamlıysa boşaltmak yerine silin: yedek yol yalnız kaldırılmış satırı arar.

Değeri Dönüştürün

  1. Kaydetme filtresine dinleyici kaydedin: her field_* anahtarı için bir kez, yazmadan önce.
  2. Okuma filtresine kaydedin: her okumada, satırlar toplandıktan sonra.
  3. İkisini simetrik tutun; yoksa profil ekranında şifreli metin kalır.
  4. Alan id'sini kontrol edin: iki filtre de her özel alan için çalışır.

Referans

Tanım İşaretleri

Altısının beşi 0 ya da 1 tutan tam sayı kolonudur; status bir dizedir ve onu diğerleri gibi ele alan kod her alanı kapalı okur.

status active ya da inactive; kapalı alan yalnız operatörün listesinde görünür.
required Boş cevap bütünlük kapısını besler; kapı müşteriyi profil ekranına yönlendirir.
uneditable Görünür ama yazılamaz; profil kaydetme döngüsü bu alanları atlar.
client_hidden Yalnız operatör ve diğerlerinin üzerinde: kayıt formundan, faturadan ve zorunlu kümeden düşer.
invoice Fatura görünümünde çıkar; boş değerler atılır.
signForm Kayıt sırasında sorulur; olmadan alana yalnız profil ekranından erişilir.

Değer Yardımcısı

coremio/helpers/User.php
// Upsert. $values bir ad => değer haritasıdır; özel alanın adı "field_{id}" biçimindedir.
// En az bir satır yazıldığında true döner.
public static function AddInfo($owner_id = 0, $values = []);
public static function setInfo($owner_id = 0, $values = []);   // AddInfo takma adı

// Okuma. $names bir dizidir (virgüllü dize de kabul edilir ve bölünür).
// İSTENEN HER ad dönen haritada bulunur; satırı olmayan ad null okunur.
// $noCache = true istek-içi hafızayı atlar; yazdıktan hemen sonra buna ihtiyacınız olur.
public static function getInfo($owner_id = 0, $names = [], $noCache = false): array;

// Satırları tamamen kaldırır. $name tek bir ad ya da ad dizisidir.
public static function deleteInfo($owner_id = 0, $name = ''): int|bool;

// Var olan bir değerin satır id'si, yoksa 0.
public static function isInfo($owner_id = 0, $name = ''): int;

// Ters arama: bu değeri hangi müşteriler taşıyor. $first = true tek satır döndürür.
public static function findInfo($name = '', $value = '', $first = true): array;

// Bütünlük kapısı. Hâlâ boş olan her şey için [alan anahtarı => etiket] döner;
// boş dizi, hesabın müşteri panelini kullanabileceği anlamına gelir.
public static function missing_required_fields($id = 0): array;
User::AddInfo() Girdi başına bir satır. phone ve company_name müşteri kaydına da yansır.
User::getInfo() İstek başına hafızalanır ve hafıza ham değeri tutar, yani okuma filtresi yine çalışır.
User::missing_required_fields() Operatörün zorunlu alanları ile yerleşik kayıt zorunluluklarını, müşterinin dili için birleştirir.
Sıra tuzağı: findInfo() Önce adı, sonra değeri alır, çünkü müşteriler arasında arar. İlk yuvaya müşteri id'si geçmek boş dizi döndürür.
Değerin biçimi Her şey metindir. checkbox virgülle birleşir; diğer dört tip düz dizedir.

İki Değer Filtresi

İkisi de referansla ateşlenir ve field_ ile başlayan anahtarlarla sınırlıdır; timezone onlara hiç ulaşmaz.

dinleyici imzaları
// User::AddInfo() içinden, insert ya da update'ten hemen önce ateşlenir.
// $value      mixed, referansla. Burada bıraktığınız şey saklanır.
// $field_id   int, "field_5" içinden ayrıştırılan tanım id'si.
// $owner_id   int, değerin ait olduğu müşteri.
Hook::add('filter:custom_field.save_value', 10, function (&$value, $field_id, $owner_id) {
    // ...
});

// User::getInfo() içinden, satırlar toplandıktan sonra ve dönüşten önce ateşlenir.
// Aynı üç argüman, aynı sıra.
Hook::add('filter:custom_field.load_value', 10, function (&$value, $field_id, $owner_id) {
    // ...
});
filter:custom_field.save_value Kalıcılaşma sınırı; aşağıdaki hiçbir katman değeri yeniden yazmaz. $value'yu yerinde değiştirin; dönüş kullanılmaz.
filter:custom_field.load_value Okuma sınırı: şifre çözün, biçimlendirin ya da saklanmayan bir değeri enjekte edin. Dönüş kullanılmaz.
action:client.profile_updated Profil kaydından sonra müşteri id'si, değişen kolonlar ve bilgi haritasıyla ateşlenir. Haritadaki anahtar kaydedildiğini gösterir, değiştiğini değil. Dönüş yoksayılır.

Tanımlar Nerelerde Okunur

Müşteriye bakan her sayfa kendi filtresini uygular ve bunlar bilerek farklıdır.

SayfaOkuyucuUyguladığı filtre
Hesap profiliHesap modelinde get_custom_fields()aktif, gizli değil, müşterinin dili, rank sırası
Kayıt formuKayıt modelinde get_custom_fields()aynısı, artı signForm = 1
Fatura görünümüinvoice_custom_fields()invoice = 1; boş değerler atılır
Tek alan doğrulamasıget_custom_field()liste filtresi, tek id'ye
Operatör sayfalarıKullanıcı modelinde get_custom_fields()yalnız dil; gizli alanlar dahil

Talep Alanları ve İki Ekseni

Aynı tanım tablosunu iki oluşturucu tüketir; iki üyelik iki ayrı yerde saklanır.

coremio/helpers/tickets.php
// Departman ekseni, talep OLUŞTURMA formu kullanır. $did = 0 her alanı döndürür.
// Satırlar yerelleştirilmiş name, description, type, properties, options ve
// department_name taşır. Sıra: did DESC, sonra rank ASC.
public static function custom_fields($lang = '', $did = 0, $status = '');

// Erişim grubu ekseni, YANIT oluşturucunun erişim bilgisi satırları kullanır. Grubun
// kendi virgüllü alan id listesini okur ve alanları TAM O SIRAYLA döndürür; bu, operatörün
// sürükle bırakla belirlediği sıradır. Boş grup [] döndürür.
public static function custom_fields_by_group($lang = '', $groupId = 0, $status = 'active');

// Seçiciyi kurmak için grupların kendisi.
public static function access_groups($lang = '', $status = 'active');
public static function get_access_group($id = 0, $lang = '', $select = '');
Tickets::custom_fields() Departman ekseni. $status boş geçilirse kapalı tanımlar da döner.
Tickets::custom_fields_by_group() Erişim grubu ekseni; değerler kendi anahtar alanıyla şifrelenir ve maskeli gösterilir.
filter:ticket.custom_fields Departman ekseni listesini filtreler (dil, departman, durum). Referansla değişir; dönüş kullanılmaz.
filter:ticket.access_group_fields Erişim grubu listesi için aynısı; dönüş kullanılmaz.
Talep alanı tipleri text, textarea, number, password, select, radio, checkbox. password temizleyiciden geçmez.

API Üzerinden

UçNe yaparNot
GET /settings/client-fieldsTanımları listelerDil bir parametredir
POST /settings/client-fieldsTek bir tanım oluştururİki dil, iki çağrı
PATCH /settings/client-fields/{id}Tek bir tanımı güncellerİşaretlerde kısmi değil: gönderilmeyen işaret 0 olur
PUT /settings/client-fields/orderListeyi sıralarRank gösterim sırasını belirler
GET /tickets/custom-fieldsTalep tanımlarını listelerAyrı motor ve kapsam

Örnek

Değeri veritabanında asla açık durmaması gereken bir alan.

coremio/hooks/acme-secure-field.php
// Aynı mantıksal alanın, kurulu her dildeki tanım id'leri. Bir müşteri alanı dil başına
// bir satırdır, yani tek bir etiket birden çok id'ye karşılık gelir.
const ACME_TAX_FIELD_IDS = [11, 12];

Hook::add('filter:custom_field.save_value', 10, function (&$value, $field_id, $owner_id) {
    if (!in_array($field_id, ACME_TAX_FIELD_IDS, true)) return;

    $value = trim((string) $value);
    if ($value === '') return;                      // boş cevap boş kalır

    $value = Crypt::encode($value, Config::get('crypt/system') . '_ACME_TAX');
});

Hook::add('filter:custom_field.load_value', 10, function (&$value, $field_id, $owner_id) {
    if (!in_array($field_id, ACME_TAX_FIELD_IDS, true)) return;
    if ((string) $value === '') return;

    // decode(), bu dinleyici var olmadan önce yazılmış bir değerde false döner; bu yüzden
    // üyenin cevabını boşaltmak yerine özgün metin korunur.
    $plain = Crypt::decode((string) $value, Config::get('crypt/system') . '_ACME_TAX');
    if ($plain !== false) $value = $plain;
});

Aynı sözleşmenin okuma tarafı; sonraki hiçbir kod değerin şifreli olduğunu bilmez.

değeri kendi kodunuzdan okumak
$uid = 42;

// İstediğiniz adları isteyin. Her ad geri döner, satırı olmayanlar null olarak.
$info = User::getInfo($uid, ['field_11', 'gsm']);
$tax  = (string) ($info['field_11'] ?? '');

// Çok seçimli bir alan, virgülle birleştirilmiş tek bir dizedir; ayırmayı siz yapın.
$picked = array_values(array_filter(explode(',', (string) ($info['field_12'] ?? ''))));

// Yazma. Aynı adlar, aynı "field_{id}" kuralı.
User::setInfo($uid, ['field_11' => 'GB123456789']);

// Okuyucu istek başına hafızaya alır; yazdıktan sonra üçüncü argümanla yeniden okuyun.
$fresh = User::getInfo($uid, ['field_11'], true);

// Bir satırı kaldırmak, boş dize yazmakla aynı şey değildir: hesabı hiç cevap vermemiş
// gibi gösteren yalnızca kaldırmadır.
if ($tax === '') User::deleteInfo($uid, ['field_11']);

Operatör tarafı, modülünüz kendi alanını getiriyorsa: kurulumda dil başına bir tanım, id'ler saklanır.

modülden tanım oluşturma
$ids = [];

foreach (['en' => 'VAT Number', 'tr' => 'Vergi Numarası'] as $lang => $label) {
    $ids[$lang] = WDB::insert('users_custom_fields', [
        'lang'          => $lang,
        'type'          => 'text',       // text | textarea | select | checkbox | radio
        'name'          => $label,
        'status'        => 'active',     // DİZE, aşağıdaki her bayrağın aksine
        'required'      => 0,
        'uneditable'    => 0,
        'client_hidden' => 0,
        'invoice'       => 1,
        'signForm'      => 1,
        'options'       => '',           // virgülle ayrılmış; select/checkbox/radio için
        'rank'          => 90,
    ]) ? WDB::lastID() : 0;
}

// Id'leri saklayın: alana giden tek kararlı tutamaktır ve dil başına farklıdır.
Config::setd('acme_vat_field_ids', Utility::jencode($ids));

Tuzaklar

Alan dil başına bir satırdır ve id'ler farklıdır

Dil sürümlerini birleştiren ortak bir üst id yoktur; birinde gizlemek diğerini görünür bırakır. Id'leri küme olarak toplayın.

Gizli artı zorunlu, müşteriyi kilitler

Kapı her zorunlu alan cevaplanana kadar profile yönlendirir, o yüzden zorunluluk sorguları gizli alanları dışlar. Kendi kuralınızı da oraya uygulayın.

Yazımı reddeden tekil aramadır

Listeden çıkarmak, sahte bir gönderimin yok saydığı bir arayüz kararıdır; yazımı asıl durduran tekil okuyucudur. Kural iki okuyucuya birden yazılır.

İşaret eklemek bir yeri değil sekiz yeri ilgilendirir

Yeni bir işaret şunları ister: kolon, yazma yolu, form ve JavaScript dalları, liste kolonu, dil anahtarları, API'nin iki yönü ve tüm müşteri sayfaları. Kolonu koddan önce uygulayın.

Fatura okuyucusu id döndürmez

Ad ve değer çiftleri verir, boş değerleri atar; id ile arayan bir test her zaman "yok" der.

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.