WordPress Yorum Alanını Özelleştirme: Alanlar ve Doğrulama

WordPress sitenizde yorum bölümü, ziyaretçilerinizle kurduğunuz en doğrudan iletişim kanallarından biridir. Ancak varsayılan WordPress yorum formu çoğu zaman ihtiyaçlarınızı tam olarak karşılamaz: bazı alanlar gereksizdir, bazıları eksiktir ve doğrulama kuralları yetersiz kalır. İşte bu noktada functions.php devreye girer. Bu yazıda, yorum alanını sıfırdan nasıl şekillendirebileceğinizi, özel alanlar ekleyebileceğinizi ve güçlü doğrulama mekanizmaları kurabileceğinizi gerçek dünya senaryolarıyla ele alacağız.

WordPress Yorum Formunun Anatomisi

WordPress yorum formu, comment_form() fonksiyonu tarafından üretilir. Bu fonksiyon $defaults adlı bir dizi alır ve bu dizi üzerinden formun neredeyse her şeyini kontrol edebilirsiniz. Temel alanlar şunlardır:

  • author: Yazar adı alanı
  • email: E-posta alanı
  • url: Web sitesi alanı
  • comment: Yorum metin alanı

Bu alanları kaldırmak, değiştirmek veya yenilerini eklemek için comment_form_default_fields ve comment_form_defaults filtrelerini kullanırsınız. Bunu bilmek, sonraki adımların mantığını anlamanızı kolaylaştırır.

Varsayılan Alanları Özelleştirme

İlk senaryomuz şu: Müşterilerinizden biri bir hukuk bürosu ve yorum formundaki “Web Sitesi” alanını gereksiz buluyor. Ayrıca placeholder metinleri Türkçe olmasını istiyor. Bunu şöyle halledebilirsiniz:

add_filter( 'comment_form_default_fields', 'ozellestir_yorum_alanlari' );
function ozellestir_yorum_alanlari( $fields ) {

    // Web sitesi alanini kaldir
    unset( $fields['url'] );

    // Yazar alanini yeniden duzenle
    $fields['author'] = '<p class="comment-form-author">
        <label for="author">' . __( 'Adınız', 'textdomain' ) . ' <span class="required">*</span></label>
        <input id="author" name="author" type="text" 
               placeholder="Adınızı ve soyadınızı girin"
               value="' . esc_attr( isset( $_POST['author'] ) ? $_POST['author'] : '' ) . '" 
               size="30" maxlength="245" required />
    </p>';

    // E-posta alanini yeniden duzenle
    $fields['email'] = '<p class="comment-form-email">
        <label for="email">' . __( 'E-posta', 'textdomain' ) . ' <span class="required">*</span></label>
        <input id="email" name="email" type="email" 
               placeholder="[email protected] (yayımlanmayacak)"
               value="' . esc_attr( isset( $_POST['email'] ) ? $_POST['email'] : '' ) . '" 
               size="30" maxlength="100" required />
    </p>';

    return $fields;
}

Bu kod, formun görünümünü hızlıca Türkçeleştirirken gereksiz alanları temizler. esc_attr() kullanımına dikkat edin, kullanıcı girdisini her zaman sanitize etmek güvenlik açısından zorunludur.

Yorum Formuna Özel Alan Ekleme

Şimdi daha ilginç bir senaryo: Bir ürün inceleme blogu için yorum formuna “Puan” alanı eklemek istiyorsunuz. Kullanıcılar 1 ile 5 arasında bir puan versin ve bu puanı yorum meta verisi olarak saklayalım.

// Forma puan alani ekle
add_filter( 'comment_form_default_fields', 'ekle_puan_alani' );
function ekle_puan_alani( $fields ) {

    $fields['puan'] = '<p class="comment-form-puan">
        <label for="puan">Puanınız <span class="required">*</span></label>
        <select name="puan" id="puan" required>
            <option value="">-- Puan Seçin --</option>
            <option value="1" ' . selected( isset($_POST['puan']) ? $_POST['puan'] : '', '1', false ) . '>⭐ 1 - Çok Kötü</option>
            <option value="2" ' . selected( isset($_POST['puan']) ? $_POST['puan'] : '', '2', false ) . '>⭐⭐ 2 - Kötü</option>
            <option value="3" ' . selected( isset($_POST['puan']) ? $_POST['puan'] : '', '3', false ) . '>⭐⭐⭐ 3 - Orta</option>
            <option value="4" ' . selected( isset($_POST['puan']) ? $_POST['puan'] : '', '4', false ) . '>⭐⭐⭐⭐ 4 - İyi</option>
            <option value="5" ' . selected( isset($_POST['puan']) ? $_POST['puan'] : '', '5', false ) . '>⭐⭐⭐⭐⭐ 5 - Mükemmel</option>
        </select>
    </p>';

    return $fields;
}

// Puani yorum meta verisi olarak kaydet
add_action( 'comment_post', 'kaydet_yorum_puani' );
function kaydet_yorum_puani( $comment_id ) {

    if ( isset( $_POST['puan'] ) && ! empty( $_POST['puan'] ) ) {
        $puan = intval( $_POST['puan'] );
        // 1-5 araliginda oldugundan emin ol
        if ( $puan >= 1 && $puan <= 5 ) {
            add_comment_meta( $comment_id, 'yorum_puani', $puan, true );
        }
    }
}

Kaydettiğiniz bu meta veriyi sonradan şöyle çekebilirsiniz:

// Herhangi bir yerde puani gostermek icin
$puan = get_comment_meta( get_comment_ID(), 'yorum_puani', true );
if ( $puan ) {
    echo '<span class="yorum-puan">Puan: ' . esc_html( $puan ) . '/5</span>';
}

Bu yaklaşım özellikle restoran, otel veya ürün inceleme sitelerinde çok işe yarıyor. Meta veri olarak saklandığı için WooCommerce entegrasyonuna da kolayca adapte edebilirsiniz.

Sunucu Taraflı Doğrulama

HTML5 required attribute’u güzel ama yeterli değil. Biri form validasyonunu devre dışı bırakıp isteği doğrudan gönderirse ne olur? Bu yüzden sunucu taraflı doğrulama şart. preprocess_comment filtresi tam bu iş için biçilmiş kaftan:

add_filter( 'preprocess_comment', 'yorum_dogrulama_kurallari' );
function yorum_dogrulama_kurallari( $commentdata ) {

    // Puan alani dogrulamasi
    if ( isset( $_POST['puan'] ) ) {
        $puan = intval( $_POST['puan'] );
        if ( $puan < 1 || $puan > 5 ) {
            wp_die(
                __( 'Hata: Lütfen 1 ile 5 arasında geçerli bir puan seçin.', 'textdomain' ),
                __( 'Yorum Hatası', 'textdomain' ),
                array( 'back_link' => true, 'response' => 400 )
            );
        }
    } else {
        // Puan secilmemisse hata ver
        wp_die(
            __( 'Hata: Puan alanı zorunludur.', 'textdomain' ),
            __( 'Yorum Hatası', 'textdomain' ),
            array( 'back_link' => true, 'response' => 400 )
        );
    }

    // Yorum uzunlugu kontrolu (minimum 20 karakter)
    $yorum_metni = trim( $commentdata['comment_content'] );
    if ( strlen( $yorum_metni ) < 20 ) {
        wp_die(
            __( 'Hata: Yorumunuz en az 20 karakter olmalıdır.', 'textdomain' ),
            __( 'Yorum Hatası', 'textdomain' ),
            array( 'back_link' => true, 'response' => 400 )
        );
    }

    // Yorum icinde URL varsa reddet (spam onlemi)
    if ( preg_match( '/https?:///i', $yorum_metni ) ) {
        wp_die(
            __( 'Hata: Yorumlar içinde link paylaşılamaz.', 'textdomain' ),
            __( 'Güvenlik Uyarısı', 'textdomain' ),
            array( 'back_link' => true, 'response' => 403 )
        );
    }

    return $commentdata;
}

Bu doğrulama bloğunda birkaç önemli nokta var. wp_die() fonksiyonunun üçüncü parametresindeki back_link => true ayarı, kullanıcının tarayıcı geri tuşuna basmasına gerek kalmadan formu düzeltemesini sağlar. HTTP response kodunu da doğru vermek (400 hatalı istek, 403 yasak) SEO ve güvenlik açısından önemlidir.

E-posta Doğrulaması ve Blacklist Kontrolü

Gerçek bir projede karşılaştığım ilginç bir senaryo: Müşteri, belirli e-posta uzantılarından yorum gelmesin istiyordu. Geçici e-posta servisleri (mailinator, guerrillamail gibi) üzerinden spam alıyordu. Bunu sunucu taraflı filtreyle çözdük:

add_filter( 'preprocess_comment', 'email_blacklist_kontrolu' );
function email_blacklist_kontrolu( $commentdata ) {

    $yasakli_domainler = array(
        'mailinator.com',
        'guerrillamail.com',
        'tempmail.com',
        'throwam.com',
        'yopmail.com',
        'sharklasers.com',
        'trashmail.com',
    );

    // Kayitli kullanici yorumlarinda bu kontrolu atlayabiliriz
    if ( is_user_logged_in() ) {
        return $commentdata;
    }

    $email = strtolower( trim( $commentdata['comment_author_email'] ) );

    // E-posta format dogrulamasi
    if ( ! filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
        wp_die(
            __( 'Hata: Geçerli bir e-posta adresi girin.', 'textdomain' ),
            __( 'Geçersiz E-posta', 'textdomain' ),
            array( 'back_link' => true, 'response' => 400 )
        );
    }

    // Domain kontrolu
    $email_parcalari = explode( '@', $email );
    $domain = isset( $email_parcalari[1] ) ? $email_parcalari[1] : '';

    if ( in_array( $domain, $yasakli_domainler ) ) {
        wp_die(
            __( 'Hata: Geçici e-posta adresleri ile yorum yapılamaz.', 'textdomain' ),
            __( 'E-posta Reddedildi', 'textdomain' ),
            array( 'back_link' => true, 'response' => 403 )
        );
    }

    return $commentdata;
}

Bu kod, geçici e-posta servislerini engellemenin yanı sıra temel format doğrulaması da yapıyor. filter_var( $email, FILTER_VALIDATE_EMAIL ) PHP’nin built-in fonksiyonu olduğu için regex yazmaya gerek kalmıyor.

Honeypot ile Spam Önleme

Bot yorumlarına karşı CAPTCHA’dan çok daha kullanıcı dostu bir yöntem: Honeypot tekniği. Görünmez bir alan eklersiniz, botlar bu alanı doldurur, siz de bu yorumları otomatik reddedersiniz. İnsan gözle göremediği için doldurmaz.

// Forma gizli honeypot alani ekle
add_filter( 'comment_form_default_fields', 'ekle_honeypot_alani' );
function ekle_honeypot_alani( $fields ) {

    // Bu alan CSS ile gizlenmeli, JS ile degil (botlar JS'i atlar)
    $fields['website_url'] = '<p class="comment-form-honeypot" 
        style="position:absolute;left:-9999px;top:-9999px;opacity:0;" 
        aria-hidden="true">
        <label for="website_url">Web Sitesi (Boş Bırakın)</label>
        <input type="text" name="website_url" id="website_url" 
               value="" tabindex="-1" autocomplete="off" />
    </p>';

    return $fields;
}

// Honeypot kontrolu
add_filter( 'preprocess_comment', 'honeypot_kontrolu', 1 );
function honeypot_kontrolu( $commentdata ) {

    // Honeypot doluysa bot demektir
    if ( ! empty( $_POST['website_url'] ) ) {
        // Sessizce basarisiz gostermek icin wp_die kullanmiyoruz
        // Bota her sey yolunda gitmis gibi gostermek daha akillica
        wp_die(
            __( 'Yorumunuz alındı, teşekkürler!', 'textdomain' ),
            __( 'Teşekkürler', 'textdomain' ),
            array( 'back_link' => false, 'response' => 200 )
        );
    }

    return $commentdata;
}

Honeypot alanının tabindex="-1" ve autocomplete="off" olması önemli. Ekran okuyucuların da bu alanı görmemesi için aria-hidden="true" ekliyoruz. Bota sahte bir başarı mesajı göstermek, “spam tespit edildi” demekten daha akıllıca bir taktik.

Yorum Formuna Checkbox ile KVKK Onayı Ekleme

Türkiye’de KVKK (Kişisel Verilerin Korunması Kanunu) kapsamında yorum formlarına açık rıza beyanı eklemek artık bir zorunluluk haline geldi. Bunu nasıl yapabiliriz:

// KVKK onay checkbox'i ekle
add_filter( 'comment_form_default_fields', 'ekle_kvkk_onay' );
function ekle_kvkk_onay( $fields ) {

    $kvkk_metni = sprintf(
        __( '<a href="%s" target="_blank">Gizlilik Politikası</a> ve <a href="%s" target="_blank">KVKK Aydınlatma Metni</a>'ni okudum, kişisel verilerimin işlenmesine onay veriyorum.', 'textdomain' ),
        esc_url( get_permalink( get_page_by_path( 'gizlilik-politikasi' ) ) ),
        esc_url( get_permalink( get_page_by_path( 'kvkk' ) ) )
    );

    $fields['kvkk_onay'] = '<p class="comment-form-kvkk">
        <input type="checkbox" name="kvkk_onay" id="kvkk_onay" value="1" required />
        <label for="kvkk_onay" class="checkbox-label">
            ' . $kvkk_metni . ' <span class="required">*</span>
        </label>
    </p>';

    return $fields;
}

// KVKK onayini sunucu tarafinda dogrula
add_filter( 'preprocess_comment', 'dogrula_kvkk_onay' );
function dogrula_kvkk_onay( $commentdata ) {

    if ( ! isset( $_POST['kvkk_onay'] ) || $_POST['kvkk_onay'] != '1' ) {
        wp_die(
            __( 'Hata: Yorum yapabilmek için KVKK onayı zorunludur.', 'textdomain' ),
            __( 'Onay Gerekli', 'textdomain' ),
            array( 'back_link' => true, 'response' => 400 )
        );
    }

    // Onayi yorum meta verisi olarak kaydet
    // Bu sayede hangi yorumun hangi tarihte onay aldigini takip edebilirsiniz
    add_action( 'comment_post', function( $comment_id ) {
        add_comment_meta( $comment_id, 'kvkk_onay_tarihi', current_time( 'mysql' ), true );
        add_comment_meta( $comment_id, 'kvkk_onay_ip', $_SERVER['REMOTE_ADDR'], true );
    });

    return $commentdata;
}

KVKK onay tarihini ve IP adresini meta veri olarak saklamak, olası bir denetimde elinizde somut kanıt bulundurmanızı sağlar. Bunu küçümsemeyin, denetimler başladığında bu kayıtlar çok işe yarıyor.

Tüm Özelleştirmeleri Bir Sınıfta Toplamak

Gerçek projelerde tüm bu fonksiyonları ayrı ayrı functions.php’ye yazmak yerine bir sınıf içinde organize etmek çok daha temiz bir yaklaşım. Özellikle birden fazla müşteri projesinde bu yapıyı kullanıyorsanız:

if ( ! class_exists( 'OzelYorumFormu' ) ) :

class OzelYorumFormu {

    public function __construct() {
        add_filter( 'comment_form_default_fields', array( $this, 'alanlari_duzenle' ) );
        add_filter( 'preprocess_comment',          array( $this, 'dogrula' ) );
        add_action( 'comment_post',                array( $this, 'meta_kaydet' ) );
    }

    public function alanlari_duzenle( $fields ) {
        unset( $fields['url'] );
        // Diger alan duzenlemeleri buraya gelir
        return $fields;
    }

    public function dogrula( $commentdata ) {
        // Tum dogrulama kurallari buraya gelir
        $this->puan_dogrula();
        $this->email_dogrula( $commentdata );
        $this->honeypot_kontrol();
        return $commentdata;
    }

    private function puan_dogrula() {
        if ( ! isset( $_POST['puan'] ) || intval( $_POST['puan'] ) < 1 || intval( $_POST['puan'] ) > 5 ) {
            wp_die( 'Geçersiz puan seçimi.', 'Hata', array( 'back_link' => true ) );
        }
    }

    private function email_dogrula( $commentdata ) {
        $email = $commentdata['comment_author_email'];
        if ( ! filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
            wp_die( 'Geçersiz e-posta adresi.', 'Hata', array( 'back_link' => true ) );
        }
    }

    private function honeypot_kontrol() {
        if ( ! empty( $_POST['website_url'] ) ) {
            wp_die( 'Teşekkürler!', 'Tamam', array( 'response' => 200 ) );
        }
    }

    public function meta_kaydet( $comment_id ) {
        if ( isset( $_POST['puan'] ) ) {
            $puan = intval( $_POST['puan'] );
            if ( $puan >= 1 && $puan <= 5 ) {
                add_comment_meta( $comment_id, 'yorum_puani', $puan, true );
            }
        }
        if ( isset( $_POST['kvkk_onay'] ) ) {
            add_comment_meta( $comment_id, 'kvkk_onay_tarihi', current_time( 'mysql' ), true );
        }
    }
}

new OzelYorumFormu();

endif;

Bu yapıyı bir plugin dosyasına ya da temanızın inc/ klasöründeki ayrı bir dosyaya alıp functions.php‘den require_once ile çağırabilirsiniz. Böylece functions.php şişmez, kod yönetimi kolaylaşır.

Dikkat Edilmesi Gereken Noktalar

Yorum formu özelleştirmesinde sık yapılan hatalar ve pratik öneriler:

  • Nonce doğrulaması: WordPress yorum formu zaten kendi nonce’unu oluşturur ama özel AJAX tabanlı yorum formları yapıyorsanız wp_verify_nonce() kullanmayı unutmayın.
  • Sanitizasyon zorunlu: Kullanıcıdan gelen her veriyi sanitize_text_field(), sanitize_email() veya intval() ile temizleyin, veritabanına ham veri yazmayın.
  • Cache uyumu: WP Super Cache veya W3 Total Cache kullanıyorsanız, yorum formu önbellekleme ile çakışabilir. DONOTCACHEPAGE sabitini ayarlamayı düşünün.
  • Tema güncellemeleri: Tüm bu kodlar functions.php‘de veya child temada durmalı, asla parent tema dosyasında değil.
  • Test ortamı: Doğrulama kurallarını canlıya almadan önce mutlaka staging ortamında test edin. Yanlış bir wp_die() çağrısı tüm yorumları engelleyebilir.
  • Erişilebilirlik: Eklediğiniz tüm alanlarda label etiketlerini doğru ilişkilendirin (for ve id eşleşmesi), ekran okuyucu kullanıcılarını ihmal etmeyin.

Sonuç

WordPress yorum formu, functions.php üzerinden inanılmaz ölçüde özelleştirilebilir bir yapıya sahip. Varsayılan alanları yeniden düzenlemekten tutun, honeypot ile spam önlemeye, KVKK onayından özel meta veri saklama sistemlerine kadar her şeyi saf PHP ve WordPress hook sistemiyle halledebiliyorsunuz. Ek bir plugin kurmaya gerek yok, performans yükü minimum.

Özellikle sunucu taraflı doğrulamayı hiçbir zaman atlamayın. Kullanıcı arayüzündeki HTML5 doğrulaması bir kolaylıktır, güvenlik değil. Gerçek koruma her zaman sunucuda gerçekleşir. KVKK uyumu ve spam önleme gibi konular artık nice to have değil, must have kategorisinde.

Bu kodları kendi projenize adapte ederken bir adım geri çekilip sorun: “Bu alanı gerçekten kullanıcıdan istemem gerekiyor mu?” Az alan, daha fazla yorum demektir. Formunuzu basit tutarken kritik doğrulamaları arka planda sağlam bir şekilde kurduğunuzda, hem kullanıcı deneyimi hem de güvenlik aynı anda kazanır.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir