Merhaba Arkadaşlar, Hayırlı Ramazanlar.
Woocommerce ile ticaret sitemi yapmaya çalışıyorum. Bir yerde takıldım. Hergün saat 11:00 ile 14:00 arasında belirli kategorilerdeki ürünlerin hepsinin otomatik 10 TL düşmesini istiyorum. 14:01 oldumu fiyatlar eski haline gelecek. Böyle bir eklenti var mı. Birde Eski fiyatının üzerinde çizgi falan olmayacak 2 fiyat gözükmeyecek tek fiyat görünecek.
şimdiden hepinize teşekkür ederim.
<?php
/**
* Plugin Name: WooCommerce CronJob Tabanlı Saatli İndirim (Varyasyon Desteği)
* Description: Sunucu cronjob ile tetiklenen REST endpointler sayesinde seçili kategorilerdeki basit & varyasyonlu ürünlerin normal fiyatını indirim yapar/günceller.
* Version: 1.0
* Author: X
* Text Domain: wc-cron-indirim
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Güvenlik: dosyaya direkt erişimi engelle
}
class WCCronDiscountPlugin {
const OPTION_NAME = 'wc_cron_discount_settings'; // Ayarların kaydedileceği option key
public function __construct() {
// Eklenti yüklenince admin ayarlarını ve REST endpointlerini kaydet
add_action( 'admin_menu', array( $this, 'register_admin_menu' ) );
add_action( 'admin_init', array( $this, 'register_settings' ) );
// REST API endpointleri
add_action( 'rest_api_init', array( $this, 'register_rest_routes' ) );
}
/**
* Admin menüde "Cron İndirim" sayfasını ekle
*/
public function register_admin_menu() {
add_menu_page(
__( 'Cron İndirim', 'wc-cron-indirim' ),
__( 'Cron İndirim', 'wc-cron-indirim' ),
'manage_options',
'wc-cron-discount-settings',
array( $this, 'settings_page_html' ),
'dashicons-clock', // Dashicon: saat ikonu
63
);
}
/**
* Ayarları kaydetmek ve form alanlarını tanımlamak
*/
public function register_settings() {
register_setting(
'wc_cron_discount_settings_group', // Settings group ID
self::OPTION_NAME, // Option name
array( $this, 'sanitize_settings' ) // Temizleme callback
);
add_settings_section(
'wc_cron_discount_main_section',
__( 'WooCommerce Cronjob Tabanlı İndirim Ayarları', 'wc-cron-indirim' ),
array( $this, 'settings_section_description' ),
'wc-cron-discount-settings'
);
// İndirim Miktarı
add_settings_field(
'discount_amount',
__( 'İndirim Miktarı (TL)', 'wc-cron-indirim' ),
array( $this, 'field_discount_amount_callback' ),
'wc-cron-discount-settings',
'wc_cron_discount_main_section'
);
// Kategori seçimi
add_settings_field(
'discount_categories',
__( 'İndirim Uygulanacak Kategoriler', 'wc-cron-indirim' ),
array( $this, 'field_discount_categories_callback' ),
'wc-cron-discount-settings',
'wc_cron_discount_main_section'
);
// Secret Key
add_settings_field(
'secret_key',
__( 'Cron Güvenlik Anahtarı (Secret Key)', 'wc-cron-indirim' ),
array( $this, 'field_secret_key_callback' ),
'wc-cron-discount-settings',
'wc_cron_discount_main_section'
);
}
/**
* Ayar grubu açıklaması
*/
public function settings_section_description() {
echo '<p>'.esc_html__( 'Sunucu cronjobunuzda bu eklentinin REST endpointlerini tetikleyerek otomatik indirim uygulayabilirsiniz.', 'wc-cron-indirim' ).'</p>';
}
/**
* Ayar değerlerini temizleme
*/
public function sanitize_settings( $input ) {
$sanitized = array();
// İndirim Miktarı
if ( isset( $input['discount_amount'] ) ) {
$sanitized['discount_amount'] = floatval( $input['discount_amount'] );
}
// Kategoriler (term id array)
if ( isset( $input['discount_categories'] ) && is_array( $input['discount_categories'] ) ) {
$sanitized['discount_categories'] = array_map( 'intval', $input['discount_categories'] );
} else {
$sanitized['discount_categories'] = array();
}
// Secret Key
if ( isset( $input['secret_key'] ) ) {
$sanitized['secret_key'] = sanitize_text_field( $input['secret_key'] );
}
return $sanitized;
}
/**
* Form alanı: İndirim Miktarı
*/
public function field_discount_amount_callback() {
$options = get_option( self::OPTION_NAME );
$discount_amount = isset( $options['discount_amount'] ) ? $options['discount_amount'] : '';
echo '<input type="number" step="0.01" name="'.self::OPTION_NAME.'[discount_amount]" value="'.esc_attr($discount_amount).'" style="width:150px;" placeholder="Ör: 10" />';
echo '<p class="description">'.esc_html__( 'Ürünlerin normal fiyatından düşülecek miktar (TL).', 'wc-cron-indirim' ).'</p>';
}
/**
* Form alanı: Kategori Seçimi (çoklu)
*/
public function field_discount_categories_callback() {
$options = get_option( self::OPTION_NAME );
$saved_cats = isset( $options['discount_categories'] ) ? (array) $options['discount_categories'] : array();
$terms = get_terms( array(
'taxonomy' => 'product_cat',
'hide_empty' => false,
) );
if ( ! empty( $terms ) && ! is_wp_error( $terms ) ) {
echo '<select name="'.self::OPTION_NAME.'[discount_categories][]" multiple style="min-width:200px; height:120px;">';
foreach ( $terms as $term ) {
$selected = in_array( $term->term_id, $saved_cats ) ? 'selected' : '';
echo '<option value="' . esc_attr( $term->term_id ) . '" ' . $selected . '>' . esc_html( $term->name ) . '</option>';
}
echo '</select>';
echo '<p class="description">'.esc_html__( 'Birden fazla kategori seçebilirsiniz (Ctrl / Cmd tuşu).', 'wc-cron-indirim' ).'</p>';
} else {
echo '<p>'.esc_html__( 'Hiç kategori bulunamadı.', 'wc-cron-indirim' ).'</p>';
}
}
/**
* Form alanı: Secret Key
*/
public function field_secret_key_callback() {
$options = get_option( self::OPTION_NAME );
$secret_key = isset( $options['secret_key'] ) ? $options['secret_key'] : '';
echo '<input type="text" name="'.self::OPTION_NAME.'[secret_key]" value="'.esc_attr($secret_key).'" style="width:300px;" placeholder="Ör: 12345abcde" />';
echo '<p class="description">'.esc_html__( 'Cron tetiklemelerinde güvenlik için kullanacağınız anahtar. URLde ?key=
şeklinde geçmelidir.', 'wc-cron-indirim' ).'</p>';
}
/**
* Admin ayar sayfasının HTML içeriği
*/
public function settings_page_html() {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
echo '<div class="wrap wc-cron-discount-admin">';
echo '<h1><span class="dashicons dashicons-clock" style="font-size: 30px; vertical-align:middle;"></span> ';
echo esc_html__( 'WooCommerce Cronjob İndirim Ayarları', 'wc-cron-indirim' ) . '</h1>';
echo '<form method="post" action="options.php" style="background:#fff; padding:20px; margin-top:15px; border:1px solid #ddd;">';
settings_fields( 'wc_cron_discount_settings_group' );
do_settings_sections( 'wc-cron-discount-settings' );
submit_button( __( 'Ayarları Kaydet', 'wc-cron-indirim' ) );
echo '</form>';
// Bilgi
$options = get_option( self::OPTION_NAME );
$secret = isset( $options['secret_key'] ) ? $options['secret_key'] : 'SECRET_KEY';
$siteurl = get_site_url( null, '', 'https' );
echo '<div style="margin-top:20px; padding:15px; background:#f9f9f9; border:1px solid #ddd;">';
echo '<h2>'.esc_html__( 'Cronjob Kullanım Bilgisi', 'wc-cron-indirim' ).'</h2>';
echo '<p>'.esc_html__( 'Sunucunuzun gerçek cron özelliğini kullanarak, belirli saatlerde bu eklentinin API uç noktalarını çağırabilirsiniz:', 'wc-cron-indirim' ).'</p>';
echo '<ul style="list-style:disc; margin-left:20px;">';
echo '<li>'.esc_html__( 'İndirim Uygula (Uygulamak için):', 'wc-cron-indirim' ).'<br />
<code>curl -X POST "' . $siteurl . '/wp-json/daily-discount/v1/apply?key=' . $secret . '"</code></li>';
echo '<li>'.esc_html__( 'İndirimi Geri Al (Fiyatları Eski Haline Döndürmek için):', 'wc-cron-indirim' ).'<br />
<code>curl -X POST "' . $siteurl . '/wp-json/daily-discount/v1/remove?key=' . $secret . '"</code></li>';
echo '</ul>';
echo '<p><strong>'.esc_html__( 'Örnek', 'wc-cron-indirim' ).':</strong> '.esc_html__( 'Her gün 11:00de indirim başlatmak için', 'wc-cron-indirim' ).'
<br /><code>0 11 * * * curl -X POST "' . $siteurl . '/wp-json/daily-discount/v1/apply?key=' . $secret . '"</code></p>';
echo '<p>'.esc_html__( 'Her gün 14:00de indirimi sonlandırmak için', 'wc-cron-indirim' ).'
<br /><code>0 14 * * * curl -X POST "' . $siteurl . '/wp-json/daily-discount/v1/remove?key=' . $secret . '"</code></p>';
echo '</div>';
echo '</div>';
}
/**
* REST API endpoint'lerini tanımla
*/
public function register_rest_routes() {
register_rest_route(
'daily-discount/v1',
'/apply',
array(
'methods' => 'POST',
'callback' => array( $this, 'rest_apply_discount' ),
)
);
register_rest_route(
'daily-discount/v1',
'/remove',
array(
'methods' => 'POST',
'callback' => array( $this, 'rest_remove_discount' ),
)
);
}
/**
* /apply endpoint'i - Cronjob tarafından tetiklenir, indirim uygular
*/
public function rest_apply_discount( $request ) {
// Güvenlik kontrolü
if ( ! $this->check_secret_key( $request ) ) {
return new WP_Error( 'forbidden', 'Geçersiz veya eksik anahtar.', array( 'status' => 403 ) );
}
$options = get_option( self::OPTION_NAME );
$discount_amount = isset( $options['discount_amount'] ) ? floatval( $options['discount_amount'] ) : 0;
$category_ids = isset( $options['discount_categories'] ) ? (array) $options['discount_categories'] : array();
if ( $discount_amount <= 0 || empty( $category_ids ) ) {
return array( 'success' => false, 'message' => 'İndirim miktarı veya kategoriler ayarlanmamış.' );
}
// Ürünleri (basit + varyasyonlu) çekmek için type => array('simple','variable') kullanıyoruz
$args = array(
'status' => 'publish',
'limit' => -1,
'type' => array( 'simple','variable' ),
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => $category_ids,
),
),
);
$products = wc_get_products( $args );
$count = 0;
foreach ( $products as $product ) {
if ( $product->is_type( 'simple' ) ) {
// Basit ürün
$this->apply_discount_to_product( $product, $discount_amount );
$count++;
} elseif ( $product->is_type( 'variable' ) ) {
// Varyasyonlu ürün: tüm varyasyonlarını çek
$variation_ids = $product->get_children();
foreach ( $variation_ids as $variation_id ) {
$variation = wc_get_product( $variation_id );
if ( $variation && $variation->is_type( 'variation' ) ) {
$this->apply_discount_to_product( $variation, $discount_amount );
$count++;
}
}
}
}
return array(
'success' => true,
'message' => 'İndirim uygulandı. Etkilenen ürün/varyasyon sayısı: ' . $count,
);
}
/**
* /remove endpoint'i - Cronjob tarafından tetiklenir, fiyatları eski haline döndürür
*/
public function rest_remove_discount( $request ) {
// Güvenlik kontrolü
if ( ! $this->check_secret_key( $request ) ) {
return new WP_Error( 'forbidden', 'Geçersiz veya eksik anahtar.', array( 'status' => 403 ) );
}
$options = get_option( self::OPTION_NAME );
$category_ids = isset( $options['discount_categories'] ) ? (array) $options['discount_categories'] : array();
if ( empty( $category_ids ) ) {
return array( 'success' => false, 'message' => 'Hiç kategori seçilmemiş.' );
}
// Basit + varyasyonlu ürünleri al
$args = array(
'status' => 'publish',
'limit' => -1,
'type' => array( 'simple','variable' ),
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => $category_ids,
),
),
);
$products = wc_get_products( $args );
$count = 0;
foreach ( $products as $product ) {
if ( $product->is_type( 'simple' ) ) {
// Basit ürün geri yükle
$this->remove_discount_from_product( $product );
$count++;
} elseif ( $product->is_type( 'variable' ) ) {
// Varyasyonlu ürünün tüm varyasyonlarını geri yükle
$variation_ids = $product->get_children();
foreach ( $variation_ids as $variation_id ) {
$variation = wc_get_product( $variation_id );
if ( $variation && $variation->is_type( 'variation' ) ) {
$this->remove_discount_from_product( $variation );
$count++;
}
}
}
}
return array(
'success' => true,
'message' => 'Fiyatlar eski haline döndü. Etkilenen ürün/varyasyon sayısı: ' . $count,
);
}
/**
* Ürüne indirim uygula (basit veya varyasyon)
*/
private function apply_discount_to_product( $product, $discount_amount ) {
$product_id = $product->get_id();
// Daha önce kaydedilmediyse eski fiyatı sakla
if ( ! get_post_meta( $product_id, '_old_regular_price', true ) ) {
$regular_price = $product->get_regular_price();
update_post_meta( $product_id, '_old_regular_price', $regular_price );
}
// Yeni fiyat
$current_price = $product->get_regular_price();
$new_price = floatval( $current_price ) - floatval( $discount_amount );
if ( $new_price < 0 ) {
$new_price = 0;
}
$product->set_regular_price( $new_price );
$product->save();
}
/**
* Üründeki indirimli fiyatı kaldır, eski fiyata döndür
*/
private function remove_discount_from_product( $product ) {
$product_id = $product->get_id();
$old_price = get_post_meta( $product_id, '_old_regular_price', true );
if ( $old_price ) {
$product->set_regular_price( $old_price );
$product->save();
// Meta bilgisini sil, bir sonrakine temiz başlansın
delete_post_meta( $product_id, '_old_regular_price' );
}
}
/**
* Secret key kontrolü (Crondan gelen istekte ?key=SECRET_KEY eşleşiyor mu?)
*/
private function check_secret_key( $request ) {
$options = get_option( self::OPTION_NAME );
$saved_key = isset( $options['secret_key'] ) ? $options['secret_key'] : '';
$given_key = $request->get_param('key');
if ( ! $saved_key || ! $given_key || $given_key !== $saved_key ) {
return false;
}
return true;
}
}
// Başlat
new WCCronDiscountPlugin();- Sunucunuzdaki (cPanel vb.) Cron Job bölümüne girin.
- İndirim başlangıç saatiniz için (örneğin her gün 11:00da) şu komutu ekleyin:
0 11 * * * curl -X POST "https://SİTEADRESİNİZ/wp-json/daily-discount/v1/apply?key=SIFRELI_ANAHTARINIZ"
- İndirim bitiş saatiniz için (örneğin her gün 14:00da) şu komutu ekleyin:
0 14 * * * curl -X POST "https://SİTEADRESİNİZ/wp-json/daily-discount/v1/remove?key=SIFRELI_ANAHTARINIZ"
- SIFRELI_ANAHTARINIZ değeri, eklentinin ayar sayfasında girdiğiniz Secret Key değeriyle aynı olmalıdır.