WooCommerce CLI ile Toplu Ürün Fiyat Güncelleme

E-ticaret sitelerinde yüzlerce, hatta binlerce ürün varken fiyat güncellemesi yapmak gerçekten baş ağrısı olabiliyor. WooCommerce admin panelinden tek tek ürün açıp fiyat değiştirmek saatler alabilirken, WP-CLI ile aynı işlemi dakikalar içinde halledebilirsiniz. Bu yazıda WooCommerce CLI komutlarını kullanarak toplu fiyat güncelleme işlemlerini nasıl yapacağınızı, gerçek dünya senaryolarıyla birlikte anlatacağım.

WP-CLI ve WooCommerce CLI Neden Bu Kadar Güçlü?

WP-CLI, WordPress’i komut satırından yönetmenizi sağlayan araç. WooCommerce de buna ek olarak kendi CLI komutlarını sunuyor. Bu ikili kombinasyon sayesinde veritabanına doğrudan müdahale etmeden, WooCommerce’in kendi API’sini kullanarak ürün verilerini güvenli şekilde düzenleyebiliyorsunuz.

Toplu fiyat güncellemede CLI kullanmanın avantajları şunlar:

  • Hız: Yüzlerce ürünü saniyeler içinde güncellersiniz
  • Güvenilirlik: WooCommerce kendi hook’larını ve validasyon mekanizmalarını çalıştırır
  • Otomasyon: Cron job ile belirli aralıklarla çalıştırabilirsiniz
  • Log tutma: Her işlemi kayıt altına alabilirsiniz
  • Geri alma: Script’i tersine çevirip eski fiyatlara dönebilirsiniz

Başlamadan önce WP-CLI’nin kurulu ve çalışır durumda olduğunu, WooCommerce’in aktif olduğunu kontrol edin.

wp --version
wp plugin is-active woocommerce && echo "WooCommerce aktif"

Temel WooCommerce Ürün Komutları

WooCommerce CLI’nin ürünlerle ilgili temel komutlarına bakalım önce. wp wc product komutu ana komutumuz.

# Mevcut komutları listele
wp wc product --help

# Tüm ürünleri listele (ilk 10)
wp wc product list --per_page=10 --user=admin

# Belirli bir ürünün detaylarını gör
wp wc product get 42 --user=admin

# Ürün sayısını öğren
wp wc product list --per_page=100 --format=count --user=admin

--user=admin parametresini her komutta kullanmanız gerekiyor, aksi halde yetki hatası alırsınız. Admin kullanıcı adınız farklıysa onu yazın.

Ürün listesini JSON formatında almak çok işe yarıyor çünkü sonra bu veriyi işleyebilirsiniz:

# JSON formatında ürün listesi al
wp wc product list --per_page=50 --format=json --user=admin | python3 -m json.tool

# Sadece ID ve fiyat bilgisini al
wp wc product list --per_page=100 --fields=id,name,price,regular_price --format=json --user=admin

Tekil Ürün Fiyat Güncelleme

Toplu işlemlere geçmeden önce tekil güncellemenin nasıl çalıştığını anlamak önemli. Bir ürünün fiyatını güncellemek için wp wc product update komutunu kullanıyoruz.

# Ürün ID'si 42 olan ürünün regular price'ını güncelle
wp wc product update 42 --regular_price=199.99 --user=admin

# Hem regular price hem sale price güncelle
wp wc product update 42 --regular_price=299.99 --sale_price=249.99 --user=admin

# Sale price'ı kaldır (indirimli fiyatı sil)
wp wc product update 42 --sale_price="" --user=admin

WooCommerce’de fiyat alanları şu şekilde çalışıyor:

  • regular_price: Normal satış fiyatı, her zaman dolu olmalı
  • sale_price: İndirimli fiyat, boş bırakılırsa indirim uygulanmaz
  • price: WooCommerce’in hesapladığı aktif fiyat, siz bunu set etmezsiniz

Bash ile Toplu Fiyat Güncelleme

Şimdi asıl konuya gelelim. Birden fazla ürünü döngü içinde güncelleyeceğiz.

Senaryo 1: Tüm Ürünlere Zam Uygulamak

Diyelim ki döviz kuru arttı ve tüm ürünlere yüzde 20 zam yapmanız gerekiyor. Bu gerçek dünyada çok sık karşılaşılan bir senaryo.

#!/bin/bash
# Dosya adı: price_increase.sh
# Tüm ürünlere belirli oranda zam yapar

WP_PATH="/var/www/html/wordpress"
WP_USER="admin"
INCREASE_PERCENT=20

echo "Fiyat güncelleme başlıyor... %${INCREASE_PERCENT} zam uygulanacak"
echo "Başlangıç zamanı: $(date)"

# Tüm ürün ID'lerini al
PRODUCT_IDS=$(wp wc product list --per_page=100 --format=json --user=$WP_USER --path=$WP_PATH | 
  python3 -c "import sys,json; ids=json.load(sys.stdin); print(' '.join([str(p['id']) for p in ids]))")

UPDATED=0
FAILED=0

for ID in $PRODUCT_IDS; do
  # Mevcut fiyatı al
  CURRENT_PRICE=$(wp wc product get $ID --format=json --user=$WP_USER --path=$WP_PATH | 
    python3 -c "import sys,json; p=json.load(sys.stdin); print(p.get('regular_price','0') or '0')")
  
  if [ "$CURRENT_PRICE" = "0" ] || [ -z "$CURRENT_PRICE" ]; then
    echo "ATLA: Ürün $ID fiyatı yok, atlanıyor"
    continue
  fi
  
  # Yeni fiyatı hesapla
  NEW_PRICE=$(python3 -c "price=float('$CURRENT_PRICE'); new=price*(1+$INCREASE_PERCENT/100); print(f'{new:.2f}')")
  
  # Güncelle
  wp wc product update $ID --regular_price=$NEW_PRICE --user=$WP_USER --path=$WP_PATH > /dev/null 2>&1
  
  if [ $? -eq 0 ]; then
    echo "TAMAM: Ürün $ID | $CURRENT_PRICE TL -> $NEW_PRICE TL"
    ((UPDATED++))
  else
    echo "HATA: Ürün $ID güncellenemedi"
    ((FAILED++))
  fi
done

echo ""
echo "=== ÖZET ==="
echo "Güncellenen: $UPDATED ürün"
echo "Hata: $FAILED ürün"
echo "Bitiş zamanı: $(date)"

Bu scripti çalıştırmadan önce test modunda deneyin, yani önce sadece echo ile ne yapacağını görün.

Senaryo 2: Belirli Kategorideki Ürünleri Güncelleme

Bazen sadece belirli bir kategorideki ürünleri güncellemek istersiniz. Mesela sadece “elektronik” kategorisindeki ürünlere indirim uygulamak gibi.

#!/bin/bash
# Belirli kategorideki ürünlere indirim uygula

WP_PATH="/var/www/html/wordpress"
WP_USER="admin"
CATEGORY_ID=15  # Elektronik kategorisi ID'si
DISCOUNT_PERCENT=15

echo "Kategori ID $CATEGORY_ID ürünlerine %$DISCOUNT_PERCENT indirim uygulanıyor..."

# Kategoriye göre ürün listesi al
PRODUCTS_JSON=$(wp wc product list 
  --category=$CATEGORY_ID 
  --per_page=100 
  --format=json 
  --user=$WP_USER 
  --path=$WP_PATH)

echo "$PRODUCTS_JSON" | python3 << 'EOF'
import sys, json, subprocess

products = json.loads(sys.stdin.read())
wp_path = "/var/www/html/wordpress"
discount = 15

print(f"Toplam {len(products)} ürün bulundu")

for product in products:
    pid = product['id']
    name = product['name']
    regular_price = product.get('regular_price', '0') or '0'
    
    if not regular_price or float(regular_price) == 0:
        print(f"ATLA: {name} (ID: {pid}) - fiyat yok")
        continue
    
    sale_price = float(regular_price) * (1 - discount/100)
    sale_price_str = f"{sale_price:.2f}"
    
    result = subprocess.run([
        'wp', 'wc', 'product', 'update', str(pid),
        f'--sale_price={sale_price_str}',
        '--user=admin',
        f'--path={wp_path}'
    ], capture_output=True, text=True)
    
    if result.returncode == 0:
        print(f"OK: {name} | Normal: {regular_price} TL | İndirimli: {sale_price_str} TL")
    else:
        print(f"HATA: {name} (ID: {pid}) - {result.stderr}")

EOF

Senaryo 3: CSV Dosyasından Fiyat Güncelleme

En profesyonel yaklaşım CSV dosyasından okuyarak güncelleme yapmak. Muhasebe departmanı size Excel’de yeni fiyatlar gönderdiğinde bu yöntemi kullanırsınız.

#!/bin/bash
# CSV'den fiyat güncelleme
# CSV formatı: product_id,regular_price,sale_price
# Örnek: 42,299.99,249.99

CSV_FILE="/tmp/new_prices.csv"
WP_PATH="/var/www/html/wordpress"
WP_USER="admin"
LOG_FILE="/var/log/price_update_$(date +%Y%m%d_%H%M%S).log"

if [ ! -f "$CSV_FILE" ]; then
  echo "Hata: $CSV_FILE bulunamadı!"
  exit 1
fi

echo "CSV fiyat güncellemesi başlıyor: $(date)" | tee $LOG_FILE
echo "Kaynak dosya: $CSV_FILE" | tee -a $LOG_FILE
echo "---" | tee -a $LOG_FILE

UPDATED=0
FAILED=0
SKIPPED=0

# CSV'yi satır satır oku (başlık satırını atla)
tail -n +2 "$CSV_FILE" | while IFS=',' read -r PRODUCT_ID REGULAR_PRICE SALE_PRICE; do
  # Boşlukları temizle
  PRODUCT_ID=$(echo $PRODUCT_ID | tr -d ' ')
  REGULAR_PRICE=$(echo $REGULAR_PRICE | tr -d ' ')
  SALE_PRICE=$(echo $SALE_PRICE | tr -d ' ')
  
  # Ürünün var olup olmadığını kontrol et
  PRODUCT_EXISTS=$(wp wc product get $PRODUCT_ID --user=$WP_USER --path=$WP_PATH --format=json 2>/dev/null | python3 -c "import sys,json; p=json.load(sys.stdin); print(p.get('id',''))" 2>/dev/null)
  
  if [ -z "$PRODUCT_EXISTS" ]; then
    MSG="ATLANDI: Ürün ID $PRODUCT_ID bulunamadı"
    echo $MSG | tee -a $LOG_FILE
    continue
  fi
  
  # Güncelleme komutunu oluştur
  if [ -n "$SALE_PRICE" ] && [ "$SALE_PRICE" != "" ]; then
    wp wc product update $PRODUCT_ID 
      --regular_price=$REGULAR_PRICE 
      --sale_price=$SALE_PRICE 
      --user=$WP_USER 
      --path=$WP_PATH > /dev/null 2>&1
  else
    wp wc product update $PRODUCT_ID 
      --regular_price=$REGULAR_PRICE 
      --user=$WP_USER 
      --path=$WP_PATH > /dev/null 2>&1
  fi
  
  if [ $? -eq 0 ]; then
    MSG="TAMAM: ID $PRODUCT_ID | Fiyat: $REGULAR_PRICE | İndirim: ${SALE_PRICE:-yok}"
    echo $MSG | tee -a $LOG_FILE
  else
    MSG="HATA: ID $PRODUCT_ID güncellenemedi"
    echo $MSG | tee -a $LOG_FILE
  fi

done

echo "---" | tee -a $LOG_FILE
echo "İşlem tamamlandı: $(date)" | tee -a $LOG_FILE
echo "Log dosyası: $LOG_FILE"

Varyasyonlu Ürünlerde Fiyat Güncelleme

WooCommerce’de varyasyonlu ürünler (variable products) biraz farklı çalışıyor. Ana ürünün fiyatı değil, her varyasyonun ayrı fiyatı var.

#!/bin/bash
# Varyasyonlu ürünlerde fiyat güncelleme

WP_PATH="/var/www/html/wordpress"
WP_USER="admin"
PARENT_PRODUCT_ID=85  # Ana ürün ID'si

echo "Ürün $PARENT_PRODUCT_ID'nin varyasyonları getiriliyor..."

# Varyasyonları listele
VARIATIONS=$(wp wc product variation list $PARENT_PRODUCT_ID 
  --format=json 
  --user=$WP_USER 
  --path=$WP_PATH)

echo "$VARIATIONS" | python3 << 'EOF'
import sys, json, subprocess

variations = json.loads(sys.stdin.read())
wp_path = "/var/www/html/wordpress"
parent_id = 85

print(f"Toplam {len(variations)} varyasyon bulundun")

for var in variations:
    var_id = var['id']
    current_price = var.get('regular_price', '0') or '0'
    attributes = var.get('attributes', [])
    attr_str = ', '.join([f"{a['name']}: {a['option']}" for a in attributes])
    
    print(f"Varyasyon ID: {var_id} | {attr_str} | Mevcut fiyat: {current_price} TL")
    
    # Örnek: Tüm varyasyonlara 10 TL ekle
    if float(current_price) > 0:
        new_price = float(current_price) + 10
        result = subprocess.run([
            'wp', 'wc', 'product', 'variation', 'update',
            str(parent_id), str(var_id),
            f'--regular_price={new_price:.2f}',
            '--user=admin',
            f'--path={wp_path}'
        ], capture_output=True, text=True)
        
        if result.returncode == 0:
            print(f"  -> Güncellendi: {new_price:.2f} TL")
        else:
            print(f"  -> HATA: {result.stderr.strip()}")

EOF

Toplu İşlemlerde Dikkat Edilmesi Gerekenler

Rate Limiting ve Sunucu Yükü

Yüzlerce ürünü tek seferde güncellemek sunucuya ciddi yük bindiriyor. Aralarına küçük bekleme süreleri ekleyin:

#!/bin/bash
# Yük dengeleme ile toplu güncelleme

WP_PATH="/var/www/html/wordpress"
WP_USER="admin"
BATCH_SIZE=10  # Her batch'te kaç ürün işlenecek
SLEEP_BETWEEN_BATCHES=2  # Batch'ler arası bekleme (saniye)

PRODUCT_IDS=(42 45 67 89 102 134 156 178 190 201 234 256)

COUNTER=0
BATCH_COUNTER=0

for ID in "${PRODUCT_IDS[@]}"; do
  wp wc product update $ID --regular_price=199.99 --user=$WP_USER --path=$WP_PATH > /dev/null 2>&1
  echo "Güncellendi: $ID"
  
  ((COUNTER++))
  
  # Her BATCH_SIZE üründen sonra bekle
  if [ $((COUNTER % BATCH_SIZE)) -eq 0 ]; then
    ((BATCH_COUNTER++))
    echo "Batch $BATCH_COUNTER tamamlandı, $SLEEP_BETWEEN_BATCHES saniye bekleniyor..."
    sleep $SLEEP_BETWEEN_BATCHES
  fi
done

echo "Tüm işlemler tamamlandı. Toplam $COUNTER ürün güncellendi."

WooCommerce Cache Temizleme

Fiyatları güncelledikten sonra önbelleği temizlemek önemli, aksi halde eski fiyatlar görünmeye devam edebilir:

# WooCommerce transient'larını temizle
wp wc tool run clear_transients --user=admin

# WordPress önbelleğini temizle
wp cache flush

# Eğer WP Super Cache kullanıyorsanız
wp super-cache flush

# WooCommerce product lookup tablosunu yenile
wp wc tool run regenerate_product_lookup_table --user=admin

Güncelleme Öncesi Yedek Alma

Toplu güncelleme yapmadan önce mutlaka yedek alın. Bu hem veritabanı hem de bir CSV yedeği şeklinde olmalı:

#!/bin/bash
# Güncelleme öncesi fiyat yedeği

WP_PATH="/var/www/html/wordpress"
WP_USER="admin"
BACKUP_FILE="/backup/prices_backup_$(date +%Y%m%d_%H%M%S).csv"

echo "product_id,name,regular_price,sale_price" > $BACKUP_FILE

wp wc product list --per_page=100 --format=json --user=$WP_USER --path=$WP_PATH | 
  python3 << EOF
import sys, json

products = json.load(sys.stdin)
backup_file = "$BACKUP_FILE"

with open(backup_file, 'a') as f:
    for p in products:
        pid = p['id']
        name = p['name'].replace(',', ' ')
        regular_price = p.get('regular_price', '') or ''
        sale_price = p.get('sale_price', '') or ''
        f.write(f"{pid},{name},{regular_price},{sale_price}n")

print(f"Yedek alındı: {len(products)} ürün -> $BACKUP_FILE")
EOF

# Ayrıca veritabanı yedeği de al
wp db export /backup/db_before_price_update_$(date +%Y%m%d_%H%M%S).sql --path=$WP_PATH
echo "Veritabanı yedeği alındı."

Cron Job ile Otomatik Fiyat Güncelleme

Kurumsal bir e-ticaret sitesinde fiyatlar sık sık değişebiliyor. Cron job ile bu süreci otomatize edebilirsiniz. Örneğin her gün sabah bir API’dan döviz kuru çekip fiyatları güncellemek gibi.

# /etc/cron.d/woocommerce-price-update dosyası
# Her gün saat 03:00'de çalışır
0 3 * * * www-data /bin/bash /opt/scripts/daily_price_update.sh >> /var/log/price_update.log 2>&1

Script içeriği:

#!/bin/bash
# /opt/scripts/daily_price_update.sh
# Günlük döviz kuruna göre fiyat güncelleme

WP_PATH="/var/www/html/wordpress"
WP_USER="admin"

# Döviz kuru çek (örnek API)
USD_RATE=$(curl -s "https://api.exchangerate.host/latest?base=USD&symbols=TRY" | 
  python3 -c "import sys,json; d=json.load(sys.stdin); print(d['rates']['TRY'])")

if [ -z "$USD_RATE" ]; then
  echo "$(date): Döviz kuru alınamadı, güncelleme atlandı" >> /var/log/price_update.log
  exit 1
fi

echo "$(date): USD/TRY kuru: $USD_RATE" >> /var/log/price_update.log

# Fiyatları güncelle
# (Burada kendi iş mantığınızı ekleyin)
wp wc product list --per_page=100 --format=json --user=$WP_USER --path=$WP_PATH | 
  python3 -c "
import sys, json, subprocess
products = json.load(sys.stdin)
usd_rate = float('$USD_RATE')

for p in products:
    # Varsayım: meta'da USD fiyatı saklı
    # Kendi senaryonuza göre uyarlayın
    pid = p['id']
    usd_price = p.get('meta_data', {})  
    # ... iş mantığı buraya
    pass
print('Güncelleme tamamlandı')
"

# Cache temizle
wp wc tool run clear_transients --user=$WP_USER --path=$WP_PATH
wp cache flush --path=$WP_PATH

Sık Karşılaşılan Hatalar ve Çözümleri

Toplu fiyat güncellemelerinde bazı hatalarla karşılaşabilirsiniz:

  • “Error: This command requires an active connection to the internet”: WP-CLI bazı durumlarda internet bağlantısı arıyor, --skip-plugins parametresi işe yarıyor
  • “Invalid parameter(s): regular_price”: Fiyat değerinde virgül yerine nokta kullandığınızdan emin olun (299,99 değil 299.99)
  • “User is not allowed to perform this action”: --user=admin parametresi eksik ya da yanlış kullanıcı adı veriyorsunuz
  • Ürünler güncelleniyor ama sitede eski fiyat görünüyor: Cache sorunu, wp cache flush ve wp wc tool run clear_transients çalıştırın
  • Script çok yavaş çalışıyor: Her ürün için iki WP-CLI çağrısı yapıyorsunuz, mümkünse ilk önce tüm ürünleri JSON olarak çekip sonra güncelleyin

Sonuç

WooCommerce CLI ile toplu fiyat güncelleme, e-ticaret sitelerinin yönetiminde ciddi zaman tasarrufu sağlıyor. Yüzlerce ürünü manuel olarak güncellemek yerine, iyi yazılmış bir bash scripti ile aynı işi dakikalar içinde halledebiliyorsunuz.

Kullandığınız scriptin mutlaka log tutmasını ve her işlem öncesinde yedek almasını öneririm. Canlı sistemlerde önce birkaç ürünle test edin, sonra tüm ürünlere uygulayın. Varyasyonlu ürünlerde wp wc product variation komutunu kullanmayı unutmayın, ana ürün üzerinden güncelleme yapmak varyasyonlara yansımıyor.

Bu teknikleri öğrendikten sonra fiyat güncelleme stresini bir daha yaşamayacaksınız. Bir sonraki yazıda WooCommerce CLI ile stok yönetimi ve sipariş durumu güncelleme konularına bakacağız.

Bir yanıt yazın

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