# Talep Alan ve Posta Kancaları

https://dev.wisecp.com/tr/talep-alan-ve-posta-kancalari

Özel alanlar ve postayla gelen taleplerin dokuz kancası.

## Genel Bakış

İki konu burada birleşir: operatörün tanımladığı **özel alanlar** ve postayla gelen taleplerin işlenmesi.

Posta kapıları diğer kapılardan ayrılır: engellemeniz hata üretmez, **sessizce atlanır**. İstenmeyen iletiyi durdurur ama iz bırakmaz; gerekçeyi kendiniz kaydetmeniz gerekir.

## Referans

### Özel alan kaydını durdurma

gateticket.custom_field.save

`AdminTickets` sıfır = yeni

Talep özel alanı kaydedilmeden önce çalışır.

Parametreler 3

$idintDüzenlenen alanın kimliği; **yeni kayıtta sıfır**.

$didintBağlı departman; **sıfır** ise alan bütün departmanlarda görünür.

$typestringAlan tipi: metin, uzun metin, parola, seçim, radyo ya da onay kutusu.

Dönüş 1

string|null**Boş olmayan bir metin işlemi engeller** ve hata olarak gösterilir. Boş dönüş devam ettirir.

Dinleyici PHP

```php
Hook::add('gate:ticket.custom_field.save', 10, function ($id, $did, $type) {
    // Sifir departman = butun departmanlarda gorunur.
    if ($type === 'password' && $did === 0)
        return 'Parola alani butun departmanlara acilamaz.';

    return null;
});
```

### Özel alan kaydını izleme

actionticket.custom_field.saved

`AdminTickets` dil verisi ayrı

Bir özel alan kaydedildikten sonra çalışır.

Parametreler 2

$fieldarrayAlanın **yapısal** kaydı: kimliği, departmanı, durumu ve sırası. Adı ve açıklaması burada **yoktur**: onlar dil kaydında durur ve ayrı okunur.

$isNewboolDoğruysa yeni oluşturuldu.

Dönüş 1

voidDönüş yoksayılır.

Dinleyici PHP

```php
Hook::add('action:ticket.custom_field.saved', 10, function ($field, $isNew) {
    // Ad ve aciklama dil kaydinda: burada yok.
    Acme::syncFieldSchema((int) ($field['id'] ?? 0));
});
```

### Özel alan silmeyi durdurma

gateticket.custom_field.delete

`AdminTickets` her zaman liste

Özel alanlar silinmeden önce çalışır.

Parametreler 1

$idarraySilinecek alanların kimlikleri. Tek silmede de **tek elemanlı dizidir**: sayı bekleyip karşılaştıran bir denetim hiçbir şey yakalamaz.

Dönüş 1

string|null**Boş olmayan bir metin işlemi engeller** ve hata olarak gösterilir. Boş dönüş devam ettirir.

Dinleyici PHP

```php
Hook::add('gate:ticket.custom_field.delete', 10, function ($id) {
    // Tek silmede bile dizidir.
    foreach ($id as $one)
        if (Acme::fieldHasData((int) $one)) return 'Doldurulmus alan silinemez.';

    return null;
});
```

### Özel alan silinmesini izleme

actionticket.custom_field.deleted

`AdminTickets` dil kaydı elinizde

Bir özel alan silindikten sonra çalışır.

Parametreler 2

$iintSilinen alanın kimliği.

$flangarrayAlanın dil kaydı, **silinmeden önce** alınmış hâliyle: adı, açıklaması ve seçenekleri. Adına ihtiyacınız varsa tek kaynağınız budur.

Dönüş 1

voidDönüş yoksayılır.

Dinleyici PHP

```php
Hook::add('action:ticket.custom_field.deleted', 10, function ($i, $flang) {
    // Ada ihtiyaciniz varsa tek kaynak dil kaydidir.
    Acme::dropFieldSchema($i, $flang['name'] ?? '');
});
```

### Özel alan listesini değiştirme

filterticket.custom_fields

`AdminTickets` bağla geçer

Özel alanlar okunduktan sonra çalışır. Kendi alanınızı listeye eklemenin yeri burasıdır.

Parametreler 2

$fieldsarraybağlaAlan satırları: kimliği, departmanı, adı, tipi ve seçenekleri.

$ctxarraybağlaBağlam: dil, departman ve durum filtresi. Departman **sıfırsa** bütün departmanlar sorgulanıyordur.

Dönüş 1

voidDönüş yoksayılır; verinin üzerine yazarsınız.

Dinleyici PHP

```php
Hook::add('filter:ticket.custom_fields', 10, function (&$fields, &$ctx) {
    // Departman sifirsa butun departmanlar sorgulaniyor.
    $fields = array_values(array_filter($fields,
        fn ($f) => Acme::fieldVisible((int) ($f['id'] ?? 0))));
});
```

### Grup alanlarını değiştirme

filterticket.access_group_fields

`AdminTickets` dil hiç boş gelmez

Bir erişim grubuna bağlı özel alanlar okunduktan sonra çalışır.

Parametreler 2

$fieldsarraybağlaGrup kapsamlı alan satırları.

$ctxarraybağlaBağlam: dil ve grup kimliği. Çağrıda boş geçilse bile dil kanca öncesinde doldurulur: **hiç boş gelmez**.

Dönüş 1

voidDönüş yoksayılır; verinin üzerine yazarsınız.

Dinleyici PHP

```php
Hook::add('filter:ticket.access_group_fields', 10, function (&$fields, &$ctx) {
    // Dil hic bos gelmez.
    $fields = Acme::orderFields($fields, $ctx['lang']);
});
```

### Gelen postayı atlatma

gateticket.pipe_import

`cronjobs` hata değil, atlama

Gelen bir e-posta talebe dönüştürülmeden önce çalışır. İstenmeyen iletileri sisteme hiç sokmamanın yeri burasıdır.

Parametreler 3

$mailarrayHam posta: konusu, gövdesi, göndereni, alıcısı, ekleri ve adresi.

$didintKaynaktan gelen departman; **sıfır** ise departman adresten çözülecektir.

$msgIdstringPostanın benzersiz kimliği.

Dönüş 1

string|null**Boş olmayan bir metin postayı tümüyle atlatır**. ? Diğer kapıların aksine **hata fırlatılmaz**: zamanlanmış görev bunu “atlandı” olarak işler ve posta işi **başarısız sayılmaz**. Yani engellemeniz sessizdir; gerekçeyi kendiniz kaydedin.

Dinleyici PHP

```php
Hook::add('gate:ticket.pipe_import', 10, function ($mail, $did, $msgId) {
    // Veto SESSIZDIR: gerekceyi kendiniz kaydedin.
    if (Acme::isAutoReply($mail)) {
        Acme::log('otomatik yanit atlandi', $msgId);
        return 'otomatik yanit';
    }

    return null;
});
```

### Postadan talep açılmasını durdurma

gateticket.open

`cronjobs` hata değil, atlama

Gelen posta bir talebe dönüşmeden hemen önce çalışır. Posta kapısından geçmiş, departmanı çözülmüş bir ileti elinizdedir.

Parametreler 6

$subjectstringTalep başlığı, normalize edilmiş hâliyle.

$messagestringİlk mesaj gövdesi.

$departmentIdintÇözümlenen departman.

$clientIdintMüşteri kimliği; **tanınmayan göndericide sıfır**.

$clientEmailstringGönderenin adresi.

$mailarrayHam posta nesnesi.

Dönüş 1

string|null**Boş olmayan bir metin talebin açılmasını engeller**. Posta kapısıyla aynı biçimde: hata fırlatılmaz, iş “atlandı” sayılır.

Dinleyici PHP

```php
Hook::add('gate:ticket.open', 10,
    function ($subject, $message, $departmentId, $clientId, $clientEmail, $mail) {
        // Taninmayan gondericide musteri kimligi SIFIR.
        if (!$clientId && Acme::strangersBlocked()) return 'taninmayan gonderici';

        return null;
    });
```

### Postadan gelen metni temizleme

filterticket.pipe_message_text

`cronjobs` ikisi de bağla

Gelen postanın gövdesi ve konusu talebe yazılmadan önce çalışır. Alıntı blokları ve imzaları kırpmanın yeri burasıdır.

Parametreler 3

$messagestringbağlaNormalize edilmiş gövde.

$subjectstringbağlaTalep konusu; referans etiketi çoktan temizlenmiştir.

$mailarrayHam posta nesnesi; bağlam içindir.

Dönüş 1

voidDönüş yoksayılır; **ikisi de** bağla geçer, ikisini de değiştirebilirsiniz.

Dinleyici PHP

```php
Hook::add('filter:ticket.pipe_message_text', 10, function (&$message, &$subject, $mail) {
    // Ikisi de baglayla gecer.
    $message = Acme::stripQuotedReply($message);
});
```

## Tuzaklar

> **Posta kapılarının vetosu sessizdir**
> 
> Diğer kapılar engellediğinde bir hata fırlatılır ve kullanıcı sebebi görür. Posta kapıları öyle değil: engellemeniz **atlandı** olarak işlenir, iş başarısız sayılmaz ve kimse bir şey görmez. İstenmeyen iletiyi durdurmak için doğru yer burasıdır, ama gerekçeyi kendiniz kaydetmezseniz iz kalmaz.

> **Alan adı yapısal kayıtta değil dil kaydındadır**
> 
> Özel alan kaydetme olayı **yapısal** satırı verir: kimlik, departman, durum, sıra. Alanın adı ve açıklaması orada **yoktur**; onlar dil kaydında durur. Adı arayan bir dinleyici boş değerle çalışır.

## İlgili Makaleler

- Destek Talebi Kancaları
- [Müşteri Hesabı Kancaları](https://dev.wisecp.com/tr/musteri-hesabi-kancalari)
- [Kancalar Nasıl Çalışır](https://dev.wisecp.com/tr/kancalar-nasil-calisir)
