WP Shell ile İnteraktif WordPress PHP Ortamı

WordPress yönetiminde zamanın büyük bir kısmı debug etmekle, veri düzeltmekle ya da “acaba bu kod ne yapıyor” sorusunu cevaplamaya çalışmakla geçer. İşte tam bu noktada wp shell komutu hayat kurtarıcı oluyor. WP-CLI’nin bu özelliği, WordPress ortamının tamamını yüklenmiş halde interaktif bir PHP yorumlayıcısına dönüştürüyor. Yani plugin fonksiyonlarını çağırabilir, veritabanı sorgularını test edebilir, kullanıcı verilerini inceleyebilir ve hepsini yapmak için tek satır kod yazmanız yeterli oluyor.

wp shell Nedir ve Neden Kullanmalısınız?

wp shell, özünde Boris veya PsySH tabanlı (kuruluma göre değişir) bir interaktif PHP REPL (Read-Eval-Print Loop) ortamıdır. WordPress’i tamamen boot ederek çalıştırır, bu sayede $wpdb, WP_Query, plugin fonksiyonları, hook sistemi, her şey kullanıma hazır olur.

Neden bu kadar işe yarar? Çünkü alternatifler oldukça zahmetlidir. Bir şeyi test etmek için ya geçici bir PHP dosyası oluşturup tarayıcıdan açarsınız, ya da özel bir WP-CLI komutu yazarsınız, ya da staging ortamına erişip wp-admin üzerinden bir şeyler denersiniz. wp shell ile bunların hiçbirini yapmanıza gerek kalmıyor.

Özellikle şu senaryolarda vazgeçilmez oluyor:

  • Veritabanı sorgularını production’a almadan önce test etmek: Bir $wpdb->update() sorgusunun doğru çalışıp çalışmadığını anlık görebilirsiniz
  • Plugin/tema fonksiyonlarını debug etmek: Bir fonksiyonun döndürdüğü değeri hemen görmek için ideal
  • Toplu veri manipülasyonu: Binlerce post için meta değeri güncellemeden önce mantığı test etmek
  • WordPress API’lerini keşfetmek: Belgelere bakmadan fonksiyonları deneyebilirsiniz

Kurulum ve Başlangıç

wp shell komutunu kullanmak için sisteminizde WP-CLI kurulu olması gerekiyor. Eğer kurulu değilse:

curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp

Kurulumu doğruladıktan sonra WordPress kurulum dizinine geçip wp shell komutunu çalıştırın:

cd /var/www/html/wordpress
wp shell

Komut çalıştıktan sonra wp> promptunu göreceksiniz. Bu, WordPress’in tamamen yüklendiği ve komutlarınızı beklediği anlamına gelir. Çıkmak için exit yazmanız veya Ctrl+D kullanmanız yeterli.

Eğer shell açılmıyorsa veya “No interactive shell is available” gibi bir hata alıyorsanız, PsySH’ı manuel olarak kurmanız gerekebilir:

wp package install wp-cli/shell-command

Temel Kullanım: İlk Adımlar

Shell açıldığında standart PHP sözdizimini kullanırsınız. Noktalı virgülleri unutmayın, yoksa shell ifadenizin devam etmesini bekler.

# WordPress sürümünü kontrol etmek
wp> echo get_bloginfo('version');

# Site URL'sini almak
wp> echo get_site_url();

# Aktif tema adını öğrenmek
wp> echo wp_get_theme()->get('Name');

Bu basit örneklerin ötesine geçelim ve gerçek senaryolara bakalım.

Senaryo 1: Veritabanı Sorguları Test Etmek

Diyelim ki bir müşterinin sitesinde tüm yayımlanmış postların başlıklarını listelemeniz gerekiyor. Production ortamına doğrudan dokunmadan önce sorgunuzu test etmek istiyorsunuz.

wp> $posts = get_posts(['post_status' => 'publish', 'numberposts' => 5]);
wp> foreach($posts as $post) { echo $post->ID . ' - ' . $post->post_title . "n"; }

Ya da direkt $wpdb nesnesini kullanarak ham SQL sorgusu çalıştırabilirsiniz:

wp> global $wpdb;
wp> $results = $wpdb->get_results("SELECT ID, post_title, post_status FROM {$wpdb->posts} WHERE post_type = 'product' AND post_status = 'publish' LIMIT 10");
wp> foreach($results as $r) { echo $r->ID . ': ' . $r->post_title . "n"; }

Bu yaklaşım özellikle WooCommerce ürünleri üzerinde çalışırken çok işe yarıyor. Bir sorgunun kaç satır döndürdüğünü görmek isterseniz:

wp> $count = $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_type = 'product' AND post_status = 'publish'");
wp> echo "Toplam ürün: " . $count;

Senaryo 2: Post Meta Değerlerini İncelemek ve Güncellemek

Bir WooCommerce mağazasında belirli ürünlerin fiyatlarını güncellemeniz gerektiğini düşünün. Önce mevcut durumu kontrol edelim:

wp> $product_id = 42;
wp> $price = get_post_meta($product_id, '_regular_price', true);
wp> $sale_price = get_post_meta($product_id, '_sale_price', true);
wp> echo "Normal fiyat: " . $price . ", İndirimli fiyat: " . $sale_price;

Değeri güncellemek için:

wp> update_post_meta($product_id, '_regular_price', '199.99');
wp> update_post_meta($product_id, '_price', '199.99');
wp> echo "Güncellendi!";

Burada dikkat edilmesi gereken bir nokta var: WooCommerce ürünleri için sadece post meta güncellemek yetmez, ürün nesnesini de temizlemeniz gerekir. Shell üzerinden bunu şöyle yapabilirsiniz:

wp> $product = wc_get_product($product_id);
wp> $product->set_regular_price('199.99');
wp> $product->save();
wp> echo "Ürün WooCommerce API'si üzerinden güncellendi";

Senaryo 3: Kullanıcı Yönetimi ve Debug

Bir kullanıcının rolünü kontrol etmek veya bir kullanıcının belirli bir capability’ye sahip olup olmadığını test etmek için:

wp> $user = get_user_by('email', '[email protected]');
wp> echo $user->ID . ' - ' . $user->display_name;
wp> print_r($user->roles);

Bir kullanıcının belirli bir işlemi yapıp yapamayacağını test etmek, özellikle karmaşık plugin izin sistemlerini debug ederken çok işe yarıyor:

wp> wp_set_current_user($user->ID);
wp> var_dump(current_user_can('edit_posts'));
wp> var_dump(current_user_can('manage_woocommerce'));

Toplu kullanıcı işlemleri için de shell idealdir. Örneğin belirli bir meta değerine sahip kullanıcıları bulmak:

wp> $users = get_users(['meta_key' => 'newsletter_subscribed', 'meta_value' => '1', 'number' => 20]);
wp> echo count($users) . " kullanıcı bulundun";
wp> foreach($users as $u) { echo $u->user_email . "n"; }

Senaryo 4: Transient ve Cache Yönetimi

Cache sorunları WordPress dünyasının en sinir bozucu problemlerinden biridir. Shell ile cache durumunu anlık inceleyebilirsiniz:

wp> $transient = get_transient('wc_product_loop_1');
wp> var_dump($transient);

Belirli bir transient’i silmek veya yeniden oluşturmak:

wp> delete_transient('wc_product_loop_1');
wp> echo "Transient silindin";

# Tüm WooCommerce transient'lerini silmek
wp> global $wpdb;
wp> $deleted = $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '%_transient_wc_%'");
wp> echo $deleted . " transient silindin";

Object cache kullanıyorsanız (Redis, Memcached gibi), cache’deki bir değeri kontrol edebilirsiniz:

wp> $cached = wp_cache_get('my_key', 'my_group');
wp> if($cached === false) { echo "Cache'de yokn"; } else { var_dump($cached); }

Senaryo 5: WP_Query ile Gelişmiş Sorgular Test Etmek

Karmaşık WP_Query sorgularını sayfaya koymadan önce shell’de test etmek çok değerli. Özellikle performans açısından kritik sorgularda bu alışkanlığı edinmek gerekiyor:

wp> $args = [
    'post_type' => 'product',
    'post_status' => 'publish',
    'posts_per_page' => -1,
    'meta_query' => [
        [
            'key' => '_stock_status',
            'value' => 'outofstock'
        ]
    ]
];
wp> $query = new WP_Query($args);
wp> echo "Stokta olmayan ürün sayısı: " . $query->found_posts;

Sorgunun ürettiği SQL’i görmek de mümkün:

wp> echo $query->request;

Bu özellik inanılmaz derecede faydalı. Yazmanız gereken WP_Query‘nin veritabanında gerçekte hangi SQL’e dönüştüğünü görürsünüz ve gerekirse optimize edebilirsiniz.

Senaryo 6: Plugin ve Hook Sistemini Debug Etmek

WordPress’in hook sistemi bazen kara kutu gibi hissettiriyor. Hangi fonksiyonların bir hook’a bağlı olduğunu shell üzerinden öğrenebilirsiniz:

wp> global $wp_filter;
wp> if(isset($wp_filter['save_post'])) {
    foreach($wp_filter['save_post']->callbacks as $priority => $callbacks) {
        echo "Priority $priority:n";
        foreach($callbacks as $cb) {
            if(is_array($cb['function'])) {
                echo "  - " . get_class($cb['function'][0]) . '::' . $cb['function'][1] . "n";
            } elseif(is_string($cb['function'])) {
                echo "  - " . $cb['function'] . "n";
            }
        }
    }
}

Aktif plugin listesini görmek ve belirli bir plugin’in aktif olup olmadığını kontrol etmek:

wp> $active_plugins = get_option('active_plugins');
wp> echo count($active_plugins) . " aktif pluginn";
wp> $woo_active = in_array('woocommerce/woocommerce.php', $active_plugins);
wp> echo "WooCommerce aktif mi? " . ($woo_active ? 'Evet' : 'Hayır') . "n";

Senaryo 7: WooCommerce Sipariş Analizi

WooCommerce mağazalarında sipariş verilerini analiz etmek sıklıkla gerekiyor. Shell üzerinden hızlı analizler yapabilirsiniz:

wp> $orders = wc_get_orders([
    'status' => ['wc-processing', 'wc-completed'],
    'limit' => 100,
    'date_created' => '>' . strtotime('-30 days'),
]);
wp> $total = 0;
wp> foreach($orders as $order) { $total += $order->get_total(); }
wp> echo "Son 30 günlük ciro: " . number_format($total, 2) . " TLn";
wp> echo "Sipariş sayısı: " . count($orders) . "n";

Belirli bir siparişin detaylarına bakmak için:

wp> $order = wc_get_order(12345);
wp> echo "Müşteri: " . $order->get_billing_first_name() . " " . $order->get_billing_last_name() . "n";
wp> echo "Toplam: " . $order->get_total() . "n";
wp> echo "Durum: " . $order->get_status() . "n";
wp> foreach($order->get_items() as $item) {
    echo "  - " . $item->get_name() . " x" . $item->get_quantity() . " = " . $item->get_total() . "n";
}

Çoklu Site (Multisite) Ortamında wp shell

WordPress multisite kurulumlarında --url parametresiyle belirli bir siteyi hedefleyebilirsiniz:

wp --url=magaza.example.com shell

Ya da shell içindeyken switch yapabilirsiniz:

wp> switch_to_blog(3);
wp> echo get_option('blogname');
wp> restore_current_blog();

Bu özellik özellikle birden fazla mağazanın veya sitenin aynı WordPress kurulumunda çalıştığı senaryolarda çok değerli oluyor.

İpuçları ve İyi Uygulamalar

Değişkenleri var_dump ile kontrol edin: echo her zaman yeterli değildir. Karmaşık nesneler veya diziler için var_dump() veya print_r() kullanın.

wp_reset_postdata() unutmayın: Shell içinde WP_Query kullandıktan sonra global post değişkenlerini sıfırlamak iyi bir alışkanlıktır.

Production’da dikkatli olun: wp shell doğrudan veritabanı üzerinde işlem yapar. Test ortamında deneyin, production’da uygulamadan önce iki kez düşünün.

Uzun komutları parça parça girin: REPL ortamı satır satır çalışır. Karmaşık bir kod bloğunu çalıştırmak istiyorsanız değişkenlere atayarak ilerleyin.

–debug flag’ini kullanın: wp shell --debug ile WP-CLI’nin hangi adımları izlediğini görebilirsiniz, bu da zor sorunları debug etmede yardımcı olur.

Tarihe bakın: Shell’e yazdığınız komutlar history’ye kaydedilmez varsayılan olarak. Önemli komutlarınızı bir yerde not alın veya doğrudan WP-CLI script’lerine taşıyın.

Aynı işlemi sürekli yapacaksanız, wp shell yerine wp eval veya wp eval-file kullanmayı tercih edin. Örneğin:

# Tek satır komut için
wp eval "echo get_option('blogname');"

# Bir PHP dosyasını WordPress ortamında çalıştırmak için
wp eval-file my-script.php

Güvenlik Notları

wp shell güçlü bir araç, ama bu gücü dikkatli kullanmak gerekiyor. Birkaç önemli nokta:

  • Shell erişimini sadece gerektiğinde kullanın ve işiniz bitince kapatın
  • Shared hosting ortamlarında wp shell‘in çalışması için proc_open PHP fonksiyonunun açık olması gerekiyor; bu bazen güvenlik açığı olarak da değerlendirilebilir
  • Canlı ortamda yapacağınız değişiklikleri önce staging’de test edin
  • wp shell ile çalışırken yaptığınız veritabanı değişikliklerini loglamak için komutları kaydetme alışkanlığı edinin

Sonuç

wp shell, bir WordPress yöneticisinin ya da geliştiricininin araç setinde olması gereken en değerli komutlardan biridir. Veritabanı sorgularını test etmekten plugin davranışlarını debug etmeye, kullanıcı yönetiminden WooCommerce sipariş analizine kadar geniş bir yelpazede kullanılabilir.

Benim kişisel rutinimde wp shell özellikle müşteri taleplerinin geldiği “acil” anlarda çok iş görüyor. “Şu ürünün fiyatını hemen güncelle” ya da “şu kullanıcının siparişlerini göster” gibi isteklerde panelden tıklamak yerine birkaç satır komutla işi bitiriyorum. Üstelik işlem geçmişini bir dosyaya kaydedip daha sonra aynı işi başka bir sitede tekrarlamak da mümkün oluyor.

En iyi öğrenme yolu denemektir. Test bir WordPress kurulumunda wp shell‘i açın ve WordPress API’lerini keşfetmeye başlayın. get_option(), get_posts(), $wpdb gibi temel fonksiyonlarla başlayıp yavaş yavaş daha karmaşık senaryolara geçin. Bir süre sonra WordPress’in iç dünyasını çok daha iyi anladığınızı ve sorunları çok daha hızlı çözdüğünüzü fark edeceksiniz.

Bir yanıt yazın

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