WordPress’te Özel Kullanıcı Rolü Oluşturma

WordPress’i kutudan çıktığı haliyle kullananlar için varsayılan roller çoğu zaman yeterli gelir. Ama gerçek dünya projelerinde işler hızla karmaşıklaşır. Bir e-ticaret sitesinde “sadece siparişleri görebilen ama ürün düzenleyemeyen” bir depo görevlisi hesabı mı lazım? Yoksa bir haber sitesinde “makale yazabilen ama yayınlayamayan” bir muhabir rolü mü? İşte bu noktada özel kullanıcı rolleri devreye girer ve functions.php dosyası senin en iyi arkadaşın olur.

WordPress Rol Sistemi Nasıl Çalışır?

WordPress kullanıcı yönetimi iki temel kavram üzerine kuruludur: roller ve yetenekler (capabilities).

Roller, bir kullanıcı grubunu tanımlayan etiketlerdir. Yetenekler ise o grubun ne yapıp yapamayacağını belirleyen izin anahtarlarıdır. Örneğin edit_posts yeteneği, bir kullanıcının yazı düzenleyebileceğini söyler. publish_posts yeteneği ise yayınlama iznini verir.

WordPress veritabanında roller wp_usermeta tablosunda wp_capabilities anahtarı altında JSON formatında saklanır. Bu yapıyı anlamak, özelleştirmeleri neden add_role() ve remove_role() gibi API fonksiyonlarıyla yapmamız gerektiğini açıklar. Direkt veritabanına yazmak yerine WordPress’in kendi fonksiyonlarını kullanmak her zaman daha güvenli ve taşınabilir bir yaklaşımdır.

Varsayılan WordPress rolleri şunlardır:

  • Subscriber: Sadece profil yönetimi yapabilir
  • Contributor: Yazı yazabilir ama yayınlayamaz
  • Author: Kendi yazılarını yayınlayabilir
  • Editor: Tüm içerikleri düzenleyebilir
  • Administrator: Her şeye tam erişim

Bu rollerin hiçbiri senin özel senaryona uymuyorsa, kendi rolünü yaratmanın zamanı gelmiş demektir.

functions.php’ye Neden Yazıyoruz?

Özel rol kodlarını bir eklenti olarak da yazabilirsin, ama functions.php küçük ve orta ölçekli projelerde en pratik yoldur. Temaya özgü işlevsellik için functions.php tercih edilirken, birden fazla temada kullanılacak rol yapılandırmaları için bir must-use plugin (wp-content/mu-plugins/) daha mantıklı olabilir.

Buradaki kritik nokta şudur: add_role() fonksiyonu her sayfa yüklemesinde çalışmamalıdır. Rol veritabanda zaten varsa tekrar eklemek sorun yaratmaz ama gereksiz veritabanı işlemi yapar. Bu yüzden genellikle tema aktivasyon hook’una veya after_switch_theme event’ine bağlarız.

Temel Rol Oluşturma

İlk örneğimizle başlayalım. En basit haliyle bir rol şöyle oluşturulur:

<?php
function create_custom_roles() {
    // Rol zaten varsa tekrar ekleme
    if ( ! get_role( 'content_editor' ) ) {
        add_role(
            'content_editor',          // Rol slug'ı (benzersiz olmalı)
            'İçerik Editörü',          // Görünen ad
            array(
                'read'                 => true,   // Dashboard'a erişim
                'edit_posts'           => true,   // Yazı düzenleme
                'edit_others_posts'    => true,   // Başkalarının yazılarını düzenleme
                'edit_published_posts' => true,   // Yayınlanmış yazıları düzenleme
                'publish_posts'        => false,  // Yayınlama YOK
                'delete_posts'         => false,  // Silme YOK
                'upload_files'         => true,   // Medya yükleme
            )
        );
    }
}
add_action( 'after_switch_theme', 'create_custom_roles' );

Bu kod, tema aktif edildiğinde bir kez çalışır. content_editor adında yeni bir rol oluşturur. Bu rol yazı yazıp düzenleyebilir, medya yükleyebilir ama yayınlama ve silme yetkisi yoktur. Bir haber sitesinde çalışan junior editörler için biçilmiş kaftan.

Kapsamlı Yetenek Listesiyle Çalışmak

Gerçek projelerde yeteneklerin tam listesini bilmek gerekir. İşte sık kullanılan yeteneklerin kategorize edilmiş hali:

Yazı (Post) Yetenekleri:

  • read: Temel okuma ve dashboard erişimi
  • edit_posts: Kendi yazılarını düzenle
  • edit_others_posts: Başkalarının yazılarını düzenle
  • edit_published_posts: Yayınlanmış yazıları düzenle
  • publish_posts: Yazı yayınla
  • delete_posts: Kendi yazılarını sil
  • delete_others_posts: Başkalarının yazılarını sil
  • delete_published_posts: Yayınlanmış yazıları sil

Sayfa (Page) Yetenekleri:

  • edit_pages: Sayfa düzenle
  • edit_others_pages: Başkalarının sayfalarını düzenle
  • publish_pages: Sayfa yayınla
  • delete_pages: Sayfa sil
  • delete_others_pages: Başkalarının sayfalarını sil

Medya Yetenekleri:

  • upload_files: Medya kütüphanesine dosya yükle
  • edit_files: Dosyaları düzenle (riskli, dikkatli kullan)

Kullanıcı Yönetimi:

  • list_users: Kullanıcıları listele
  • edit_users: Kullanıcıları düzenle
  • create_users: Yeni kullanıcı oluştur
  • delete_users: Kullanıcı sil
  • promote_users: Kullanıcı rollerini değiştir

Yorum Yetenekleri:

  • moderate_comments: Yorumları onayla/reddet
  • edit_comment: Yorum düzenle

Tema ve Eklenti:

  • switch_themes: Tema değiştir (güvenlik riski, dikkatli ver!)
  • activate_plugins: Eklenti aktif et (güvenlik riski!)
  • install_plugins: Eklenti yükle
  • update_plugins: Eklenti güncelle

Gerçek Dünya Senaryosu: WooCommerce Mağaza Yöneticisi

Diyelim ki bir e-ticaret müşterisi var. Depo personeli siparişleri takip edip düzenleyebilmeli ama ürün fiyatlarına, müşteri verilerine veya ödeme ayarlarına dokunamaz. Bu klasik bir senaryo:

<?php
function create_warehouse_role() {
    if ( ! get_role( 'warehouse_staff' ) ) {
        add_role(
            'warehouse_staff',
            'Depo Personeli',
            array(
                'read'              => true,
                // WooCommerce sipariş yetenekleri
                'edit_shop_orders'         => true,
                'read_shop_orders'         => true,
                'edit_others_shop_orders'  => true,
                'publish_shop_orders'      => true,
                // Ürün görüntüleme (sadece okuma)
                'read_product'             => true,
                // Temel dashboard
                'view_woocommerce_reports' => true,
            )
        );
    }
}
add_action( 'after_switch_theme', 'create_warehouse_role' );

Bu rol, depo personelinin siparişleri görmesine ve durumlarını güncellemesine izin verir. Ürünleri, müşteri listelerini veya ödeme ayarlarını göremezler.

Mevcut Role Yetenek Ekleme ve Çıkarma

Bazen sıfırdan rol yaratmak yerine mevcut bir rolü modifiye etmek gerekir. Bunun için add_cap() ve remove_cap() metodlarını kullanırız:

<?php
function modify_editor_capabilities() {
    $editor = get_role( 'editor' );
    
    if ( $editor ) {
        // Editor rolüne kullanıcı listeleme yetkisi ver
        $editor->add_cap( 'list_users' );
        
        // Editor rolünden tema değiştirme yetkisini al
        // (Aslında editor'da zaten yok ama örnek olsun)
        $editor->remove_cap( 'switch_themes' );
        
        // WooCommerce ürün yetenekleri ekle
        $editor->add_cap( 'edit_products' );
        $editor->add_cap( 'publish_products' );
        $editor->add_cap( 'delete_products' );
    }
}
add_action( 'init', 'modify_editor_capabilities' );

Önemli uyarı: init hook’unda yetenek değişikliği her sayfa yüklemesinde veritabanına yazma işlemi yapar. Bu performans sorununa yol açabilir. Daha iyi yaklaşım, bunu bir kez çalıştırmak için aktivasyon hook’unu kullanmak veya eklenti aktivasyon fonksiyonu yazmaktır.

Tek Seferlik Çalıştırma için Doğru Yöntem

Production ortamında role işlemlerini her yüklemede tekrar etmemek için şu pattern’i kullan:

<?php
function setup_custom_roles_once() {
    // Transient kontrolü ile tek seferlik çalıştırma
    if ( get_transient( 'custom_roles_created' ) ) {
        return;
    }
    
    // Muhasebe Uzmanı rolü
    if ( ! get_role( 'accountant' ) ) {
        add_role(
            'accountant',
            'Muhasebe Uzmanı',
            array(
                'read'                      => true,
                'view_woocommerce_reports'  => true,
                'manage_woocommerce'        => false,
                'read_shop_orders'          => true,
                'edit_shop_orders'          => false,
            )
        );
    }
    
    // SEO Uzmanı rolü
    if ( ! get_role( 'seo_specialist' ) ) {
        add_role(
            'seo_specialist',
            'SEO Uzmanı',
            array(
                'read'                 => true,
                'edit_posts'           => true,
                'edit_others_posts'    => true,
                'edit_published_posts' => true,
                'publish_posts'        => true,
                'upload_files'         => true,
                'edit_pages'           => true,
                'edit_others_pages'    => true,
                'manage_categories'    => true,
            )
        );
    }
    
    // Bir hafta boyunca tekrar çalışma
    set_transient( 'custom_roles_created', true, WEEK_IN_SECONDS );
}
add_action( 'init', 'setup_custom_roles_once' );

Bu yaklaşım transient kullanarak fonksiyonun bir hafta boyunca tekrar çalışmasını engeller. Rollerde değişiklik yapman gerekirse transient’i manuel silip sayfayı yenile.

Rol Silme İşlemi

Artık kullanılmayan rolleri temizlemek de önemli bir bakım adımıdır. Tema değiştirildiğinde veya proje bittiğinde rolleri silmek için:

<?php
function remove_custom_roles() {
    $custom_roles = array(
        'warehouse_staff',
        'content_editor',
        'accountant',
        'seo_specialist',
    );
    
    foreach ( $custom_roles as $role_slug ) {
        if ( get_role( $role_slug ) ) {
            // Bu rolün atandığı kullanıcıları subscriber'a düşür
            $users_with_role = get_users( array( 'role' => $role_slug ) );
            foreach ( $users_with_role as $user ) {
                $user->set_role( 'subscriber' );
            }
            
            // Rolü sil
            remove_role( $role_slug );
        }
    }
}
// Tema devre dışı bırakıldığında rolleri temizle
add_action( 'switch_theme', 'remove_custom_roles' );

Bu kod tema değiştirildiğinde özel rolleri temizler ve o rollerdeki kullanıcıları subscriber’a düşürür. Kullanıcıların sistemde rollersiz kalmasını engellemek için bu adım kritiktir.

Dinamik Yetenek Kontrolü: Kısıtlı Admin Paneli

Özel roller oluşturduktan sonra, bu rollerin dashboard’da neye erişip erişemeyeceğini daha da rafine etmek isteyebilirsin. Aşağıdaki kod, depo personelinin sadece belirli menüleri görmesini sağlar:

<?php
function restrict_dashboard_for_warehouse_staff() {
    // Sadece warehouse_staff rolü için uygula
    if ( ! current_user_can( 'edit_shop_orders' ) || current_user_can( 'manage_woocommerce' ) ) {
        return;
    }
    
    // Gereksiz menü öğelerini kaldır
    $menus_to_remove = array(
        'index.php',           // Dashboard widget'ları
        'edit.php',            // Yazılar
        'edit.php?post_type=page', // Sayfalar
        'themes.php',          // Görünüm
        'plugins.php',         // Eklentiler
        'users.php',           // Kullanıcılar
        'tools.php',           // Araçlar
        'options-general.php', // Ayarlar
    );
    
    foreach ( $menus_to_remove as $menu ) {
        remove_menu_page( $menu );
    }
    
    // WooCommerce alt menülerini de temizle
    remove_submenu_page( 'woocommerce', 'wc-settings' );
    remove_submenu_page( 'woocommerce', 'wc-reports' );
}
add_action( 'admin_menu', 'restrict_dashboard_for_warehouse_staff' );

Dikkat: remove_menu_page() sadece menüyü gizler, sayfayı erişilemez kılmaz. Gerçek güvenlik için yetenek kontrollerini mutlaka doğru yapılandırman gerekir. Menü gizleme yalnızca UX (kullanıcı deneyimi) amaçlıdır.

Özel Yazı Tiplerine Özel Yetenekler

Özel yazı tipleri (Custom Post Types) kayıt edilirken capability_type ve map_meta_cap parametreleriyle o yazı tipine özgü yetenekler oluşturabilirsin. Bu yetenekleri özel rollerine eklemek son derece güçlü bir yapı sağlar:

<?php
// Önce özel yazı tipini 'map_meta_cap' ile kaydet
function register_event_post_type() {
    $args = array(
        'label'           => 'Etkinlikler',
        'public'          => true,
        'capability_type' => 'event',  // Özel yetenek tipi
        'map_meta_cap'    => true,     // Otomatik yetenek haritalama
        'capabilities'    => array(
            'edit_post'              => 'edit_event',
            'read_post'              => 'read_event',
            'delete_post'            => 'delete_event',
            'edit_posts'             => 'edit_events',
            'edit_others_posts'      => 'edit_others_events',
            'publish_posts'          => 'publish_events',
            'read_private_posts'     => 'read_private_events',
            'delete_posts'           => 'delete_events',
            'delete_private_posts'   => 'delete_private_events',
            'delete_published_posts' => 'delete_published_events',
            'delete_others_posts'    => 'delete_others_events',
            'edit_private_posts'     => 'edit_private_events',
            'edit_published_posts'   => 'edit_published_events',
            'create_posts'           => 'create_events',
        ),
    );
    register_post_type( 'event', $args );
}
add_action( 'init', 'register_event_post_type' );

// Şimdi bu yetenekleri özel role ekle
function create_event_manager_role() {
    if ( ! get_role( 'event_manager' ) ) {
        add_role(
            'event_manager',
            'Etkinlik Yöneticisi',
            array(
                'read'                    => true,
                'upload_files'            => true,
                // Etkinliğe özgü yetenekler
                'edit_event'              => true,
                'read_event'              => true,
                'delete_event'            => true,
                'edit_events'             => true,
                'edit_others_events'      => true,
                'publish_events'          => true,
                'delete_events'           => true,
                'delete_published_events' => true,
                'edit_published_events'   => true,
                'create_events'           => true,
                // Standart yazılara erişim yok
                'edit_posts'              => false,
            )
        );
    }
}
add_action( 'after_switch_theme', 'create_event_manager_role' );

Bu yapıyla etkinlik yöneticileri sadece “Etkinlikler” yazı tipini yönetebilir, standart blog yazılarına, sayfalara veya WooCommerce ürünlerine dokunamazlar.

Rolleri Debug Etme

Bazen bir rolün hangi yeteneklere sahip olduğunu kontrol etmek gerekir. Bunu geliştirme ortamında şöyle yapabilirsin:

<?php
// Geliştirme ortamında rol yeteneklerini debug et
function debug_role_capabilities( $role_slug ) {
    if ( ! WP_DEBUG ) {
        return;
    }
    
    $role = get_role( $role_slug );
    
    if ( $role ) {
        $active_caps = array_filter( $role->capabilities, function( $value ) {
            return $value === true;
        });
        
        error_log( '=== ' . strtoupper( $role_slug ) . ' ROL YETENEKLERİ ===' );
        error_log( 'Aktif yetenekler: ' . implode( ', ', array_keys( $active_caps ) ) );
        error_log( 'Toplam yetenek sayısı: ' . count( $active_caps ) );
    } else {
        error_log( $role_slug . ' rolü bulunamadı!' );
    }
}

// Admin panel yüklendiğinde çalıştır (sadece development'ta)
add_action( 'admin_init', function() {
    if ( WP_DEBUG && current_user_can( 'administrator' ) ) {
        debug_role_capabilities( 'warehouse_staff' );
        debug_role_capabilities( 'event_manager' );
    }
});

Bu debug fonksiyonu wp-content/debug.log dosyasına rollerin aktif yeteneklerini yazar. WP_DEBUG aktif olmadığında sessiz kalır.

Sık Yapılan Hatalar ve Çözümleri

Rol her yüklemede yeniden oluşturulduğunda ne olur?

add_role() zaten var olan bir rolü geçmez, hata da vermez. Ama veritabanını gereksiz yere sorgular. Bu yüzden get_role() kontrolü veya transient kullanımı şarttır.

Kullanıcının yetenek değişikliklerini görmesi neden gecikebilir?

WordPress kullanıcı yeteneklerini session bazlı cache’ler. Yetenek değişikliği yaptıktan sonra etkilenen kullanıcının çıkış yapıp tekrar giriş yapması gerekebilir.

manage_options yetkisi neden bu kadar kritik?

Bu yetenek, WordPress ayarlar sayfalarının tamamına erişim verir. Hiçbir zaman Subscriber veya Contributor gibi düşük seviye rollere bu yetkiyi verme. Site konfigürasyonunu tamamen açmış olursun.

Multisite kurulumda ne farklı?

Multisite’da add_role() sadece o anki site için rol oluşturur. Ağdaki tüm sitelere rol eklemek için her site için ayrı ayrı çalıştırman gerekir veya switch_to_blog() ile döngü kurman gerekir.

Güvenlik Prensipleri

Özel rol oluştururken şu güvenlik prensiplerine sadık kalmak sysadmin’in sorumluluğudur:

  • En az yetki prensibi: Kullanıcıya sadece işini yapması için gereken minimum yetkileri ver. Ekstra vermek kolaydır ama sonradan geri almak zahmetlidir.
  • Yetenek gruplaması: Birbiriyle mantıksal ilişkisi olan yetenekleri birlikte düşün. edit_others_posts veriyorsan edit_published_posts de gerekli olabilir.
  • Test ortamında dene: Production’da rol değişikliği yapmadan önce staging ortamında test et. Yanlış bir yetenek konfigürasyonu site güvenliğini tehlikeye atabilir.
  • Kod incelemesi: Rolleri değiştiren kodları mutlaka başka bir göz geçirsin. Özellikle manage_options veya activate_plugins gibi kritik yetenekler söz konusuysa.

Sonuç

WordPress kullanıcı rol sistemi, doğru kullanıldığında ekip iş akışlarını ciddi şekilde iyileştiren güçlü bir araçtır. functions.php veya must-use plugin aracılığıyla yazdığın rol kodu, onlarca kullanıcıya farklı erişim seviyeleri tanımlamanı ve bunları merkezi bir yerden yönetmeni sağlar.

Özellikle büyüyen ajans projelerinde, WooCommerce mağazalarında ve çok yazarlı bloglarda özel rol yönetimi bir lüks değil, zorunluluktur. Muhasebecinin sipariş raporlarını görmesi ama ürün fiyatlarını değiştirememesi, depo personelinin kargo durumunu güncellemesi ama müşteri verilerine ulaşamaması, bunların hepsi iyi kurgulanmış bir rol mimarisiyle çözülür.

Son olarak şunu hatırlatmak isterim: Rol ve yetenek yönetimi salt bir teknik mesele değil, aynı zamanda veri güvenliği ve kurumsal sorumluluk meselesidir. Her yetki verdiğin kullanıcı, sitenin güvenlik yüzeyini genişletir. Bu yüzden rol tasarımını bir güvenlik mimarisi olarak yaklaşarak yap, kullanıcı isteklerini olduğu gibi karşılamak yerine gerçekten neye ihtiyaç duyduklarını analiz et.

Bir yanıt yazın

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