WooCommerce CLI ile Ürün Durumu Toplu Değiştirme
E-ticaret sitelerini yönetirken en can sıkıcı işlerden biri onlarca, hatta yüzlerce ürünün durumunu tek tek değiştirmek zorunda kalmaktır. Sezon sonu kampanyası bitti, stok tükendi, ya da toplu bir ürün grubunu geçici olarak devre dışı bırakmak istiyorsun. WooCommerce arayüzünden bunu yapmaya çalışıyorsun ve her ürün için ayrı ayrı tıklıyorsun. Bu tam bir eziyet. İşte tam bu noktada WP-CLI devreye giriyor ve hayatını kurtarıyor.
WP-CLI ile WooCommerce Yönetimine Giriş
WP-CLI, WordPress’i komut satırından yönetmeni sağlayan resmi araç. WooCommerce de bu araca kendi komut setini eklemiş durumda. wp wc ile başlayan komutlar sayesinde ürünler, siparişler, müşteriler ve daha fazlası üzerinde toplu işlemler yapabiliyorsun.
Başlamadan önce sisteminde WP-CLI’ın kurulu ve çalışır durumda olduğundan emin ol:
wp --version
wp plugin list --allow-root | grep woocommerce
WooCommerce aktif değilse komutlar çalışmaz. Ayrıca WP-CLI’ın WooCommerce eklentisini tanıyabilmesi için WooCommerce’in 3.0 ve üzeri sürümde olması gerekiyor. Eski sürümlerde wp wc komutları ya hiç çalışmaz ya da eksik çalışır.
Kullanıcı yetkisi konusuna da dikkat etmek gerekiyor. WooCommerce REST API komutları bir kullanıcı bağlamında çalışır. Bunun için --user parametresini kullanman gerekiyor:
wp wc product list --user=admin --allow-root
Bu komut sana mevcut ürünlerin listesini verir. Çıktıya baktığında her ürünün ID, adı, durumu ve diğer bilgilerini görürsün.
Ürün Durumları Nelerdir?
WooCommerce’de bir ürünün alabileceği başlıca durumlar şunlardır:
- publish: Ürün yayında ve müşteriler görebilir
- draft: Taslak halinde, yayında değil
- pending: İnceleme bekliyor
- private: Sadece yöneticiler görebilir
- trash: Çöp kutusuna taşınmış
Bunlar aslında WordPress’in post status sistemidir. WooCommerce ürünleri teknik olarak custom post type olduğu için aynı durum sistemi geçerli.
Tek Ürünün Durumunu Değiştirme
Toplu işlemlere geçmeden önce tekil işlemleri anlayalım. Bir ürünün ID’sini biliyorsan durumunu değiştirmek tek satır:
wp wc product update 123 --status=draft --user=admin --allow-root
Bu komut 123 numaralı ürünü taslak durumuna çeker. Başarılı olursa terminal sana şu çıktıyı verir:
Success: Updated product 123.
Ürünün mevcut durumunu kontrol etmek için:
wp wc product get 123 --user=admin --allow-root --format=json | python3 -m json.tool | grep status
Ya da daha temiz bir yol:
wp wc product get 123 --field=status --user=admin --allow-root
Toplu Durum Değiştirme: Temel Yöntem
Asıl güç toplu işlemlerde. Diyelim ki tüm taslak ürünleri yayına almak istiyorsun. Bunu bir döngüyle yapabilirsin:
wp wc product list --status=draft --field=id --user=admin --allow-root |
while read id; do
wp wc product update "$id" --status=publish --user=admin --allow-root
echo "Ürün $id yayına alındı"
done
Bu komut önce tüm taslak ürünlerin ID listesini alır, sonra her birini sırayla yayına alır. Terminal’e her işlem için onay mesajı yazar, böylece neyin yapıldığını takip edebilirsin.
Aynı mantıkla tüm yayındaki ürünleri taslağa çekebilirsin:
wp wc product list --status=publish --field=id --user=admin --allow-root |
while read id; do
wp wc product update "$id" --status=draft --user=admin --allow-root
done
Ancak dikkat et. Yüzlerce ürününüz varsa bu işlem uzun sürebilir. Her wp wc product update çağrısı ayrı bir PHP süreci başlatır ve REST API üzerinden işlem yapar. 500 ürün için ciddi bir süre geçebilir.
Performansı Artırma: WP-CLI Eval ile Direkt DB İşlemleri
Büyük miktarda ürün için doğrudan WordPress fonksiyonlarını kullanan wp eval ya da wp eval-file çok daha hızlı çalışır:
wp eval '
$args = array(
"post_type" => "product",
"post_status" => "draft",
"posts_per_page" => -1,
"fields" => "ids"
);
$products = get_posts($args);
foreach ($products as $id) {
wp_update_post(array("ID" => $id, "post_status" => "publish"));
echo "Guncellendi: " . $id . "n";
}
echo "Toplam: " . count($products) . " urun guncellendi.n";
' --allow-root
Bu yöntem wp wc product update komutunu her ürün için ayrı ayrı çağırmak yerine tek bir PHP sürecinde tüm işlemi halleder. 500 ürün için dakikalar yerine saniyeler içinde tamamlanır.
Gerçek Dünya Senaryosu 1: Sezon Sonu Ürünlerini Devre Dışı Bırakma
Diyelim ki bir giyim mağazası işletiyorsun. Kış sezonu bitti ve “kış” kategorisindeki tüm ürünleri taslağa çekmek istiyorsun. Önce kategori ID’sini bul:
wp term list product_cat --fields=term_id,name --allow-root | grep -i kis
Diyelim ki “kış” kategorisinin ID’si 15 çıktı. Şimdi bu kategorideki tüm yayındaki ürünleri taslağa çek:
wp eval '
$args = array(
"post_type" => "product",
"post_status" => "publish",
"posts_per_page" => -1,
"fields" => "ids",
"tax_query" => array(
array(
"taxonomy" => "product_cat",
"field" => "term_id",
"terms" => array(15)
)
)
);
$products = get_posts($args);
$count = 0;
foreach ($products as $id) {
wp_update_post(array("ID" => $id, "post_status" => "draft"));
$count++;
echo "Taslaglandi: #" . $id . "n";
}
echo "nToplam " . $count . " urun taslaga alindi.n";
' --allow-root
Bu senaryo gerçek bir mağaza operasyonunda çok işe yarar. Sezon başında da tam tersi işlemi yaparak hepsini tekrar yayına alabilirsin.
Gerçek Dünya Senaryosu 2: Stokta Olmayan Ürünleri Gizleme
Stokta olmayan ürünleri yayında tutmak SEO açısından tartışmalı ama kullanıcı deneyimi açısından kötü. Stok durumu “outofstock” olan ürünleri private yaparak arama motorlarından gizlemeden müşterilerden saklayabilirsin:
wp eval '
$args = array(
"post_type" => "product",
"post_status" => "publish",
"posts_per_page" => -1,
"fields" => "ids",
"meta_query" => array(
array(
"key" => "_stock_status",
"value" => "outofstock",
"compare" => "="
)
)
);
$products = get_posts($args);
$count = 0;
foreach ($products as $id) {
wp_update_post(array("ID" => $id, "post_status" => "private"));
$count++;
}
echo $count . " urun private yapildi.n";
' --allow-root
Stok tekrar geldiğinde bu ürünleri geri yayına almak için stok durumu “instock” olanları tekrar publish yapabilirsin. Ama dikkat, bu sefer private ürünleri taramalısın:
wp eval '
$args = array(
"post_type" => "product",
"post_status" => "private",
"posts_per_page" => -1,
"fields" => "ids",
"meta_query" => array(
array(
"key" => "_stock_status",
"value" => "instock",
"compare" => "="
)
)
);
$products = get_posts($args);
$count = 0;
foreach ($products as $id) {
wp_update_post(array("ID" => $id, "post_status" => "publish"));
$count++;
}
echo $count . " urun tekrar yayina alindi.n";
' --allow-root
Bash Script ile Profesyonel Toplu Değiştirme
Tekrar kullanabileceğin bir bash script hazırlamak en iyi pratik. Bu script ile hem durum değiştirme hem de log tutma işini halledebilirsin:
#!/bin/bash
# WooCommerce Toplu Urun Durum Degistirici
# Kullanim: ./wc-status-change.sh [kaynakDurum] [hedefDurum] [kategoriID]
SOURCE_STATUS=${1:-"draft"}
TARGET_STATUS=${2:-"publish"}
CATEGORY_ID=${3:-""}
WP_PATH="/var/www/html"
LOG_FILE="/var/log/wc-status-change-$(date +%Y%m%d-%H%M%S).log"
WP_USER="admin"
echo "Islem basladi: $(date)" | tee -a "$LOG_FILE"
echo "Kaynak durum: $SOURCE_STATUS" | tee -a "$LOG_FILE"
echo "Hedef durum: $TARGET_STATUS" | tee -a "$LOG_FILE"
if [ -n "$CATEGORY_ID" ]; then
echo "Kategori ID: $CATEGORY_ID" | tee -a "$LOG_FILE"
PRODUCT_IDS=$(wp wc product list
--status="$SOURCE_STATUS"
--category="$CATEGORY_ID"
--field=id
--user="$WP_USER"
--allow-root
--path="$WP_PATH"
--format=ids 2>/dev/null)
else
PRODUCT_IDS=$(wp wc product list
--status="$SOURCE_STATUS"
--field=id
--user="$WP_USER"
--allow-root
--path="$WP_PATH"
--format=ids 2>/dev/null)
fi
if [ -z "$PRODUCT_IDS" ]; then
echo "Hicbir urun bulunamadi. Islem sonlandirildi." | tee -a "$LOG_FILE"
exit 0
fi
TOTAL=$(echo "$PRODUCT_IDS" | wc -w)
echo "Toplam $TOTAL urun bulundu." | tee -a "$LOG_FILE"
COUNTER=0
for ID in $PRODUCT_IDS; do
RESULT=$(wp wc product update "$ID"
--status="$TARGET_STATUS"
--user="$WP_USER"
--allow-root
--path="$WP_PATH" 2>&1)
COUNTER=$((COUNTER + 1))
echo "[$COUNTER/$TOTAL] Urun #$ID: $RESULT" | tee -a "$LOG_FILE"
done
echo "Islem tamamlandi: $(date)" | tee -a "$LOG_FILE"
echo "Toplam $COUNTER urun guncellendi." | tee -a "$LOG_FILE"
echo "Log dosyasi: $LOG_FILE"
Bu scripti kullanmak için:
chmod +x wc-status-change.sh
# Tum taslak urunleri yayina al
./wc-status-change.sh draft publish
# Sadece 15. kategorideki yayindakileri taslaklastir
./wc-status-change.sh publish draft 15
Cron ile Otomatik Zamanlı Durum Değiştirme
Kampanya dönemi bittikten sonra ürünleri otomatik olarak devre dışı bırakmak istiyorsan cron ile bu işi otomatize edebilirsin. Diyelim her Pazar gecesi yarısı “haftalık-kampanya” kategorisindeki ürünleri taslağa çekeceksin:
# Crontab'a ekle
crontab -e
Şu satırı ekle:
0 0 * * 0 /bin/bash /root/scripts/wc-status-change.sh publish draft 22 >> /var/log/wc-cron.log 2>&1
Pazartesi sabahı 08:00’de tekrar yayına alma için:
0 8 * * 1 /bin/bash /root/scripts/wc-status-change.sh draft publish 22 >> /var/log/wc-cron.log 2>&1
Durum Değiştirme Öncesi Yedek Alma
Toplu değişiklik yapmadan önce mutlaka bir yedek almak iyi bir alışkanlık. En azından hangi ürünlerin değiştiğini kaydetmelisin:
# Degisiklik oncesi ID listesini kaydet
wp wc product list --status=publish --field=id --user=admin --allow-root
--path=/var/www/html > /tmp/publish_products_backup_$(date +%Y%m%d).txt
echo "Yedek alindi. Toplam urun:"
wc -l /tmp/publish_products_backup_$(date +%Y%m%d).txt
Geri alma gerekirse bu dosyayı kullanarak her şeyi eski haline getirebilirsin:
# Geri alma islemi
while IFS= read -r id; do
wp wc product update "$id" --status=publish --user=admin --allow-root
done < /tmp/publish_products_backup_20241215.txt
Varyasyonlu Ürünlerde Dikkat Edilmesi Gerekenler
WooCommerce’de varyasyonlu ürünler (variable products) biraz farklı çalışır. Bir variable product’ı draft’a çektiğinde varyasyonlar da otomatik olarak görünmez olur, ancak varyasyon postları veritabanında “publish” olarak kalır. Bu genellikle sorun çıkarmaz ama bilmekte fayda var.
Varyasyonları ayrıca yönetmek istersen:
wp eval '
$parent_id = 123; // Variable product ID
$variations = get_posts(array(
"post_type" => "product_variation",
"post_parent" => $parent_id,
"post_status" => "publish",
"posts_per_page" => -1,
"fields" => "ids"
));
foreach ($variations as $var_id) {
wp_update_post(array("ID" => $var_id, "post_status" => "private"));
echo "Varyasyon #" . $var_id . " gizlendi.n";
}
' --allow-root
Sık Karşılaşılan Hatalar ve Çözümleri
“Error: ‘wc’ is not a registered wp command” hatası alıyorsan WooCommerce aktif değil ya da WP-CLI WooCommerce eklentisini görmüyor demektir. Önce kontrol et:
wp plugin list --allow-root | grep -i woocommerce
wp plugin activate woocommerce --allow-root
“You don’t have permission” hatası genellikle --user parametresini vermediğin zamanlarda çıkar. WooCommerce REST API komutları için admin yetkisine sahip bir kullanıcı gereklidir.
Büyük sitelerde timeout veya memory hatası alıyorsan wp eval içinde ürünleri sayfalı işlemeyi dene:
wp eval '
$batch_size = 50;
$page = 1;
$total = 0;
do {
$products = get_posts(array(
"post_type" => "product",
"post_status" => "draft",
"posts_per_page" => $batch_size,
"paged" => $page,
"fields" => "ids"
));
foreach ($products as $id) {
wp_update_post(array("ID" => $id, "post_status" => "publish"));
$total++;
}
$page++;
echo "Sayfa " . ($page-1) . " tamamlandi. Toplam: " . $total . "n";
} while (count($products) === $batch_size);
echo "Tum islem tamamlandi. Toplam: " . $total . " urun.n";
' --allow-root
WP-CLI ile Durum Kontrolü ve Raporlama
İşlem yaptıktan sonra durumu doğrulamak için basit bir rapor komutu işe yarar:
echo "=== WooCommerce Urun Durum Raporu ==="
for STATUS in publish draft pending private; do
COUNT=$(wp wc product list --status="$STATUS" --user=admin --allow-root --format=ids 2>/dev/null | wc -w)
echo "$STATUS: $COUNT urun"
done
echo "====================================="
Bu çıktı sana mevcut durumu net bir şekilde gösterir ve yaptığın değişiklikleri doğrulamana yardımcı olur.
Sonuç
WP-CLI ile WooCommerce ürün durumlarını toplu değiştirmek, manuel arayüz işlemlerine kıyasla hem çok daha hızlı hem de çok daha güvenilir. Yüzlerce ürünü birkaç saniyede güncelleyebilir, bu işlemleri log dosyasına kaydedebilir ve cron ile tamamen otomatize edebilirsin.
Bu yazıda öğrendiklerimizi özetleyecek olursak:
wp wc product updatekomutu tekil ve toplu durum değişikliği için temel araçwp evalile doğrudan WordPress fonksiyonları kullanmak büyük veri setlerinde çok daha performanslı- Bash script yazarak log tutmak ve yeniden kullanılabilir otomasyon sağlamak iyi bir pratik
- Toplu işlem öncesi yedek almak zorunlu bir adım olmalı
- Varyasyonlu ürünlerin davranışı farklı olduğu için ayrıca test etmek gerekiyor
Sysadmin olarak WooCommerce mağazalarını yönetiyorsan bu komutları araç kutuna eklemek, sezon değişimlerinde, kampanya yönetiminde ve stok güncellemelerinde sana ciddi zaman kazandıracak. Bir kez script haline getirip otomatize ettiğinde bir daha arayüzden tek tek tıklamak zorunda kalmayacaksın.
