ویجت محصول متغییر

باکس افزودن به سبد خرید حرفه ای برای محصولات متغییر + کد رایگان همراه با آموزش

کد افزونه که باید در سایت قرار بگیره ٬قسمت functions.php قالب در ادامه این شرت کد و در جای مد نظر در قالب محصول قرار دهید : اگه برای متغییر های مختلف تصاویر متفاوتی دارید و برای هر متغییر ٬

کد افزونه که باید در سایت قرار بگیره ٬قسمت functions.php قالب

				
					/**
 * ویجت محصول WooCommerce با قابلیت AJAX و انیمیشن قیمت
 * نسخه: 2.4 (با انیمیشن شمارشگر قیمت)
 * 
 * نحوه استفاده:
 * 1. این کد را در فایل functions.php قالب خود قرار دهید
 * 2. یا از شورت‌کد استفاده کنید: [product_widget] یا [product_widget id="123"]
 * 3. یا مستقیماً در فایل‌های PHP
 */

// جلوگیری از دسترسی مستقیم
if (!defined('ABSPATH')) {
    exit;
}

// بررسی فعال بودن WooCommerce
if (!function_exists('is_plugin_active')) {
    include_once(ABSPATH . 'wp-admin/includes/plugin.php');
}

if (!in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {
    return;
}

/**
 * تابع تبدیل اعداد انگلیسی به فارسی
 */
if (!function_exists('convert_to_persian_numbers')) {
    function convert_to_persian_numbers($string) {
        $persian_numbers = array('۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹');
        $english_numbers = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');
        return str_replace($english_numbers, $persian_numbers, $string);
    }
}

/**
 * تابع اصلی ویجت محصول
 */
function custom_product_widget($product_id = null) {
    global $product;
    
    // ایجاد ID یکتا برای هر ویجت
    static $widget_counter = 0;
    $widget_counter++;
    $unique_id = 'widget-' . $widget_counter . '-' . time();
    
    // اگر product_id ارسال نشده، محصول فعلی را بگیر
    if (!$product_id && is_product()) {
        $current_product = $product;
    } elseif ($product_id) {
        $current_product = wc_get_product($product_id);
    } else {
        return '<p style="color: #dc2626; text-align: center; padding: 20px;">محصولی یافت نشد</p>';
    }
    
    if (!$current_product || !is_object($current_product)) {
        return '<p style="color: #dc2626; text-align: center; padding: 20px;">محصول معتبر نیست</p>';
    }
    
    // دریافت اطلاعات محصول با بررسی خالی بودن
    $product_price = $current_product->get_price();
    $regular_price = $current_product->get_regular_price();
    $sale_price = $current_product->get_sale_price();
    $is_on_sale = $current_product->is_on_sale();
    $is_variable = $current_product->is_type('variable');
    $is_in_stock = $current_product->is_in_stock();
    $stock_status = $current_product->get_stock_status();
    $stock_quantity = $current_product->get_stock_quantity();
    $manage_stock = $current_product->get_manage_stock();
    
    // تبدیل قیمت‌ها به عدد و بررسی معتبر بودن
    $product_price = !empty($product_price) ? floatval($product_price) : 0;
    $regular_price = !empty($regular_price) ? floatval($regular_price) : 0;
    $sale_price = !empty($sale_price) ? floatval($sale_price) : 0;
    
    // محاسبه درصد تخفیف
    $discount_percentage = 0;
    if ($is_on_sale && $regular_price > 0 && $sale_price > 0) {
        $discount_percentage = round((($regular_price - $sale_price) / $regular_price) * 100);
    }
    
    // تعیین حداکثر تعداد قابل خرید
    $max_quantity = 9999;
    if ($manage_stock && $stock_quantity > 0) {
        $max_quantity = $stock_quantity;
    }
    
    // اگر قیمت‌ها صفر یا خالی هستند، از قیمت نمایشی استفاده کن
    if ($product_price <= 0) {
        $display_price = $current_product->get_price_html();
        if (empty($display_price)) {
            return '<p style="text-align: center; padding: 20px; background: #f3f4f6; border-radius: 8px;">برای اطلاع از قیمت این محصول تماس بگیرید، شماره تماس: 09128008175</p>'; 
        }
    }
    
    ob_start();
?>
    
    <style>
        .custom-product-widget {
            width: 100%;
            max-width: none;
            position: relative;
            overflow: hidden;
            font-family: 'shabnam' ;
            direction: rtl;
            box-sizing: border-box;
        }

        .custom-product-widget.out-of-stock {
            background: #f8fafc;
            border-color: #e2e8f0;
        }

        .custom-product-widget.out-of-stock * {
            color: #64748b !important;
        }

        .widget-stock-message {
            text-align: center;
            padding: 12px;
            background: #fef2f2;
            color: #dc2626;
            border-radius: 8px;
            font-size: 14px;
            font-weight: 500;
            margin-bottom: 20px;
            border: 1px solid #fecaca;
        }

        .widget-price-section {
            text-align: center;
            margin-bottom: 20px;
            padding: 16px;
            background: #ffff;
            border-radius: 12px;
            position: relative;
        }

        .widget-price-title {
            font-size: 16px !important;
            font-weight: 600 !important;
            color: #8B8E92 !important; 
            margin-bottom: 12px;
            text-align: center;
        }

        .widget-price-container {
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 12px;
            flex-wrap: wrap;
            transition: all 0.3s ease;
            min-height: 60px;
        }

        .widget-price-container.updating {
            opacity: 1;
        }

        .widget-price-wrapper {
            display: flex;
            align-items: center;
            gap: 12px;
            flex-wrap: wrap;
            justify-content: center;
        }

        .widget-price {
            font-size: 24px;
            font-weight: 700;
            color: #1a202c;
            transition: all 0.3s ease;
            display: inline-block;
        }

        .widget-price.price-changing {
            animation: priceChange 0.5s ease;
            color: #F85811;
        }

        @keyframes priceChange {
            0%, 100% { transform: scale(1); }
            50% { transform: scale(1.15); }
        }

        .widget-price.loading {
            opacity: 0;
            transform: scale(0.8) translateY(-10px);
        }

        .widget-regular-price {
            font-size: 16px;
            color: #9ca3af;
            text-decoration: line-through;
            font-weight: 400;
            transition: all 0.3s ease;
            opacity: 0;
            transform: translateX(-20px);
        }

        .widget-regular-price.show {
            opacity: 1;
            transform: translateX(0);
            animation: slideInRight 0.5s ease;
        }

        @keyframes slideInRight {
            0% {
                opacity: 0;
                transform: translateX(-30px);
            }
            100% {
                opacity: 1;
                transform: translateX(0);
            }
        }

        .widget-sale-price {
            font-size: 28px;
            font-weight: 700;
            color: #059669;
            transition: all 0.3s ease;
            opacity: 0;
            transform: scale(0.8);
        }

        .widget-sale-price.show {
            opacity: 1;
            transform: scale(1);
            animation: popIn 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55);
        }

        @keyframes popIn {
            0% {
                opacity: 0;
                transform: scale(0.5) rotate(-5deg);
            }
            50% {
                transform: scale(1.1) rotate(2deg);
            }
            100% {
                opacity: 1;
                transform: scale(1) rotate(0deg);
            }
        }

        .widget-currency {
            font-size: 12px;
            color: #64748b;
            margin-right: 6px;
            font-weight: 400;
        }

        .widget-discount-badge {
            display: inline-flex;
            align-items: center;
            background: linear-gradient(135deg, #ef4444, #dc2626);
            color: white;
            padding: 6px 12px;
            border-radius: 8px;
            font-size: 13px;
            font-weight: 600;
            white-space: nowrap;
            box-shadow: 0 2px 8px rgba(239, 68, 68, 0.3);
            opacity: 0;
            transform: scale(0.5) rotate(-10deg);
        }

        .widget-discount-badge.show {
            opacity: 1;
            transform: scale(1) rotate(0deg);
            animation: discountPop 0.8s cubic-bezier(0.68, -0.55, 0.265, 1.55) 0.3s forwards;
        }

        @keyframes discountPop {
            0% {
                opacity: 0;
                transform: scale(0.3) rotate(-15deg);
            }
            60% {
                transform: scale(1.2) rotate(5deg);
            }
            80% {
                transform: scale(0.95) rotate(-2deg);
            }
            100% {
                opacity: 1;
                transform: scale(1) rotate(0deg);
            }
        }

        .widget-attributes-section {
            margin-bottom: 20px;
        }

        .widget-attribute-group {
            margin-bottom: 18px;
        }

        .widget-attribute-label {
            display: block;
            font-weight: 700;
            color: #374151;
            margin-bottom: 12px;
            font-size: 22px;
			text-align: center;
        }

        .widget-attribute-options {
            display: flex;
            flex-wrap: wrap;
            gap: 10px;
            padding: 5px;
            justify-content: center;
        }

        .widget-attribute-option {
            padding: 10px 18px;
            border: 2px solid #e5e7eb;
            border-radius: 25px;
            background: white;
            cursor: pointer;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            font-size: 14px;
            font-weight: 500;
            color: #374151;
            position: relative;
        }

        .widget-attribute-option:hover:not(.out-of-stock *):not(.selected) {
            border-color: #F85811;
            background: #fff5f0;
            color: #1f2937;
            transform: translateY(-2px);
        }

        .widget-attribute-option.selected {
            background: #1f2937;
            border-color: #1f2937;
            color: white;
            transform: translateY(-1px);
            animation: fillAnimation 0.4s cubic-bezier(0.4, 0, 0.2, 1);
        }

        @keyframes fillAnimation {
            0% {
                background: white;
                color: #374151;
                transform: scale(0.95);
            }
            50% {
                transform: scale(1.05);
            }
            100% {
                background: #1f2937;
                color: white;
                transform: translateY(-1px) scale(1);
            }
        }

        .widget-cart-section {
            display: flex;
            align-items: center;
            gap: 8px;
            justify-content: center;
            margin-top: 24px;
        }

        .widget-quantity-selector {
            display: flex;
            align-items: center;
            gap: 4px;
            background: white;
            border: 1px solid #e5e7eb;
            border-radius: 8px;
            padding: 2px;
            transition: all 0.3s ease;
        }

        .widget-quantity-selector.hidden {
            display: none;
        }

        .widget-quantity-btn {
            width: 28px;
            height: 40px;
            border: none;
            background: #f3f4f6;
            color: #374151;
            border-radius: 4px;
            cursor: pointer;
            font-size: 16px;
            font-weight: 600;
            transition: all 0.2s ease;
            display: flex;
            align-items: center;
            justify-content: center;
            flex-shrink: 0;
        }

        .widget-quantity-btn:hover:not(:disabled) {
            background: #F85811;
            color: white;
            transform: scale(1.05);
        }

        .widget-quantity-btn:disabled {
            opacity: 0.3;
            cursor: not-allowed;
        }

        .widget-quantity-input {
            width: 45px;
            text-align: center;
            border: 0px solid white !important;
            background: transparent;
            font-size: 14px;
            font-weight: 600;
            color: #1f2937;
            outline: none;
        }

        .widget-quantity-input::-webkit-inner-spin-button,
        .widget-quantity-input::-webkit-outer-spin-button {
            -webkit-appearance: none;
            margin: 0;
        }

        .widget-add-to-cart-btn {
            flex: 1;
            max-width: 280px;
            padding: 10px 20px;
            background: #F85811;
            color: white;
            border: none;
            border-radius: 8px;
            font-size: 15px;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.2s ease;
            position: relative;
            overflow: hidden;
            min-height: 44px;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .widget-add-to-cart-btn:hover:not(:disabled) {
            background: #d94a0d;
            transform: translateY(-2px);
            box-shadow: 0 4px 12px rgba(248, 88, 17, 0.3);
        }

        .widget-add-to-cart-btn:disabled {
            background: #9ca3af;
            cursor: not-allowed;
        }

        .widget-add-to-cart-btn.hidden {
            display: none;
        }

        .widget-add-to-cart-btn.loading {
            pointer-events: none;
            opacity: 0.7;
        }

        .widget-spinner {
            display: none;
            width: 16px;
            height: 16px;
            border: 2px solid transparent;
            border-top: 2px solid white;
            border-radius: 50%;
            animation: widget-spin 1s linear infinite;
            margin-right: 8px;
        }

        .widget-add-to-cart-btn.loading .widget-spinner {
            display: inline-block;
        }

        @keyframes widget-spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }

        .widget-success-message {
            position: fixed;
            top: 20px;
            right: 20px;
            background: linear-gradient(135deg, #059669, #047857);
            color: white;
            padding: 16px 24px;
            border-radius: 12px;
            box-shadow: 0 8px 25px rgba(5, 150, 105, 0.3);
            transform: translateX(400px);
            transition: all 0.4s cubic-bezier(0.68, -0.55, 0.265, 1.55);
            z-index: 9999;
            font-weight: 500;
            display: none;
            font-size: 14px;
            max-width: 350px;
            border: 1px solid rgba(255, 255, 255, 0.2);
        }

        .widget-success-message.show {
            display: block;
            transform: translateX(0);
        }

        .widget-success-message a {
            color: rgba(255, 255, 255, 0.9);
            text-decoration: none;
            padding: 4px 8px;
            background: rgba(255, 255, 255, 0.1);
            border-radius: 4px;
            transition: background 0.2s ease;
            margin-right: 8px;
        }

        .widget-success-message a:hover {
            background: rgba(255, 255, 255, 0.2);
            color: white;
        }

        .widget-stock-info {
            text-align: center;
            font-size: 13px;
            color: #6b7280;
            margin-top: 8px;
        }

        .widget-stock-info.low-stock {
            color: #f59e0b;
            font-weight: 600;
        }

        @media (max-width: 640px) {
            .custom-product-widget {
                padding: 16px;
                margin: 10px 0;
            }
            
            .widget-price-wrapper {
                flex-wrap: wrap;
                gap: 8px;
            }
            
            .widget-discount-badge {
                font-size: 11px;
                padding: 3px 8px;
            }
            
            .widget-attribute-label {
                font-size: 15px;
                margin-bottom: 10px;
            }
            
            .widget-attribute-option {
                padding: 6px 12px;
                font-size: 13px;
            }
            
            .widget-cart-section {
                flex-direction: row;
                gap: 10px;
                align-items: center;
                justify-content: space-between;
            }
            
            .widget-quantity-selector {
                width: auto;
                flex-shrink: 0;
                border-width: 2px;
            }
            
            .widget-quantity-btn {
                width: 10px;
                height: 10px;
                font-size: 14px;
				padding : 0px ;
            }
            
            .widget-quantity-input {
               padding:0px !important;
				height:37px;
                font-size: 15px;
            }
            
            .widget-add-to-cart-btn {
                flex: 1;
                max-width: none;
                padding: 12px 16px;
                font-size: 14px;
                height: 44px;
                min-height: 44px;
            }
            
            .widget-attribute-options {
                justify-content: center;
                gap: 8px;
            }
            
            .widget-price {
                font-size: 24px;
            }
            
            .widget-sale-price {
                font-size: 24px;
            }
            
            .widget-regular-price {
                font-size: 14px;
            }
        }
    </style>
    
    <div class="custom-product-widget <?php echo !$is_in_stock ? 'out-of-stock' : ''; ?>" 
         data-product-id="<?php echo esc_attr($current_product->get_id()); ?>"
         data-widget-id="<?php echo esc_attr($unique_id); ?>"
         data-has-price="<?php echo $product_price > 0 ? '1' : '0'; ?>"
         data-in-stock="<?php echo $is_in_stock ? '1' : '0'; ?>"
         data-max-quantity="<?php echo esc_attr($max_quantity); ?>"
         data-manage-stock="<?php echo $manage_stock ? '1' : '0'; ?>">
        
        <?php if (!$is_in_stock): ?>
        <div class="widget-stock-message">
            <?php echo $stock_status === 'outofstock' ? 'این محصول در حال حاضر موجود نمی‌باشد' : 'موجودی این محصول به اتمام رسیده است'; ?>
        </div>
        <?php endif; ?>

        <!-- بخش قیمت -->
        <div class="widget-price-section">
            <h2 class="widget-price-title">قیمت محصول</h2>
            
            <div class="widget-price-container" id="widget-price-<?php echo esc_attr($unique_id); ?>">
                <?php if ($product_price > 0): ?>
                    <?php if ($is_on_sale && $regular_price > 0 && $sale_price > 0): ?>
                        <div class="widget-price-wrapper">
                            <div class="widget-regular-price">
                                <?php echo convert_to_persian_numbers(number_format($regular_price, 0, '.', ',')); ?>
                                <span class="widget-currency">تومان</span>
                            </div>
                            <div class="widget-sale-price">
                                <?php echo convert_to_persian_numbers(number_format($sale_price, 0, '.', ',')); ?>
                                <span class="widget-currency">تومان</span>
                            </div>
                            <div class="widget-discount-badge">
                                <?php echo convert_to_persian_numbers($discount_percentage); ?>% تخفیف
                            </div>
                        </div>
                    <?php else: ?>
                        <div class="widget-price">
                            <?php echo convert_to_persian_numbers(number_format($product_price, 0, '.', ',')); ?>
                            <span class="widget-currency">تومان</span>
                        </div>
                    <?php endif; ?>
                <?php else: ?>
                    <div class="widget-price">
                        <?php echo wp_kses_post($current_product->get_price_html()); ?>
                    </div>
                <?php endif; ?>
            </div>
        </div>

        <!-- بخش ویژگی‌ها فقط برای محصولات متغیر -->
        <?php if ($is_variable && $current_product->get_available_variations()): ?>
        <div class="widget-attributes-section">
            <?php
            $available_variations = $current_product->get_available_variations();
            $variation_attributes = $current_product->get_variation_attributes();
            
            // دریافت ویژگی‌های پیش‌فرض محصول
            $default_attributes = $current_product->get_default_attributes();
            
            foreach ($variation_attributes as $attribute_name => $options) {
                $attribute_label = wc_attribute_label($attribute_name);
                $clean_attribute_name = 'attribute_' . sanitize_title($attribute_name);
                
                // تعیین مقدار پیش‌فرض
                $default_value = '';
                if (isset($default_attributes[sanitize_title($attribute_name)])) {
                    $default_value = $default_attributes[sanitize_title($attribute_name)];
                } elseif (!empty($options)) {
                    // اگر پیش‌فرض تعریف نشده، اولین گزینه را انتخاب کن
                    $default_value = reset($options);
                }
                
                // بررسی اینکه آیا ویژگی از taxonomy است یا custom
                $is_taxonomy = taxonomy_exists($attribute_name);
                
                ?>
                <div class="widget-attribute-group">
                    <label class="widget-attribute-label"><?php echo esc_html($attribute_label); ?>:</label>
                    <div class="widget-attribute-options">
                        <?php foreach ($options as $option): 
                            // دریافت نام نمایشی واقعی
                            if ($is_taxonomy) {
                                $term = get_term_by('slug', $option, $attribute_name);
                                $display_name = $term ? $term->name : $option;
                            } else {
                                // برای ویژگی‌های سفارشی (custom attributes)
                                $display_name = $option;
                            }
                        ?>
                        <div class="widget-attribute-option <?php echo ($option === $default_value) ? 'selected' : ''; ?>" 
                             data-attribute="<?php echo esc_attr($clean_attribute_name); ?>" 
                             data-value="<?php echo esc_attr($option); ?>"
                             data-widget-id="<?php echo esc_attr($unique_id); ?>">
                            <?php echo esc_html($display_name); ?>
                        </div>
                        <?php endforeach; ?>
                    </div>
                </div>
                <?php
            }
            ?>
            
            <script type="application/json" id="variations-data-<?php echo esc_attr($unique_id); ?>">
                <?php echo wp_json_encode($available_variations); ?>
            </script>
        </div>
        <?php endif; ?>

        <!-- بخش افزودن به سبد خرید -->
        <div class="widget-cart-section">
            <div class="widget-quantity-selector <?php echo (!$is_in_stock || $product_price <= 0) ? 'hidden' : ''; ?>" 
                 data-widget-id="<?php echo esc_attr($unique_id); ?>">
                <button type="button" class="widget-quantity-btn widget-quantity-decrease" data-widget-id="<?php echo esc_attr($unique_id); ?>">−</button>
                <input type="number" 
                       class="widget-quantity-input" 
                       value="1" 
                       min="1" 
                       max="<?php echo esc_attr($max_quantity); ?>"
                       data-widget-id="<?php echo esc_attr($unique_id); ?>"
                       readonly>
                <button type="button" class="widget-quantity-btn widget-quantity-increase" data-widget-id="<?php echo esc_attr($unique_id); ?>">+</button>
            </div>
            
            <button class="widget-add-to-cart-btn <?php echo (!$is_in_stock || $product_price <= 0) ? 'hidden' : ''; ?>" 
                    data-widget-id="<?php echo esc_attr($unique_id); ?>"
                    data-product-id="<?php echo esc_attr($current_product->get_id()); ?>">
                <div class="widget-spinner"></div>
                <span>افزودن به سبد خرید</span>
            </button>
        </div>
        
        <?php if ($is_in_stock && $manage_stock && $stock_quantity > 0 && $stock_quantity <= 5): ?>
        <div class="widget-stock-info low-stock">
            تنها <?php echo convert_to_persian_numbers($stock_quantity); ?> عدد در انبار باقی مانده
        </div>
        <?php endif; ?>
    </div>

    <div class="widget-success-message" id="widget-success-message-<?php echo esc_attr($unique_id); ?>">
        محصول با موفقیت به سبد خرید اضافه شد!
    </div>

    <script type="pmdelayedscript" data-cfasync="false" data-no-optimize="1" data-no-defer="1" data-no-minify="1" data-rocketlazyloadscript="1">
    (function() {
        'use strict';
        
        var widgetId = '<?php echo esc_js($unique_id); ?>';
        var productId = <?php echo esc_js($current_product->get_id()); ?>;

        document.addEventListener('DOMContentLoaded', function() {
            var widget = document.querySelector('.custom-product-widget[data-widget-id="' + widgetId + '"]');
            var quantityInput = document.querySelector('.widget-quantity-input[data-widget-id="' + widgetId + '"]');
            var decreaseBtn = document.querySelector('.widget-quantity-decrease[data-widget-id="' + widgetId + '"]');
            var increaseBtn = document.querySelector('.widget-quantity-increase[data-widget-id="' + widgetId + '"]');
            var quantitySelector = document.querySelector('.widget-quantity-selector[data-widget-id="' + widgetId + '"]');
            var addToCartBtn = document.querySelector('.widget-add-to-cart-btn[data-widget-id="' + widgetId + '"]');
            
            var variationsData = document.getElementById('variations-data-' + widgetId);
            var availableVariations = [];
            
            if (variationsData) {
                try {
                    availableVariations = JSON.parse(variationsData.textContent);
                } catch (e) {
                    console.error('خطا در پارس کردن داده‌های variations:', e);
                }
            }

            // مدیریت دکمه‌های تعداد
            if (decreaseBtn && quantityInput) {
                decreaseBtn.addEventListener('click', function() {
                    var currentValue = parseInt(quantityInput.value) || 1;
                    if (currentValue > 1) {
                        quantityInput.value = currentValue - 1;
                        updateQuantityButtons();
                    }
                });
            }

            if (increaseBtn && quantityInput) {
                increaseBtn.addEventListener('click', function() {
                    var currentValue = parseInt(quantityInput.value) || 1;
                    var maxQuantity = parseInt(quantityInput.getAttribute('max')) || 9999;
                    if (currentValue < maxQuantity) {
                        quantityInput.value = currentValue + 1;
                        updateQuantityButtons();
                    }
                });
            }

            function updateQuantityButtons() {
                if (!quantityInput || !decreaseBtn || !increaseBtn) return;
                
                var currentValue = parseInt(quantityInput.value) || 1;
                var maxQuantity = parseInt(quantityInput.getAttribute('max')) || 9999;
                
                decreaseBtn.disabled = currentValue <= 1;
                increaseBtn.disabled = currentValue >= maxQuantity;
                
                // مخفی کردن دکمه افزودن اگر تعداد بیشتر از موجودی باشد
                if (currentValue > maxQuantity && addToCartBtn) {
                    addToCartBtn.classList.add('hidden');
                    if (quantitySelector) quantitySelector.classList.add('hidden');
                } else {
                    if (widget.dataset.hasPrice === '1' && widget.dataset.inStock === '1') {
                        addToCartBtn.classList.remove('hidden');
                        if (quantitySelector) quantitySelector.classList.remove('hidden');
                    }
                }
            }

            // مدیریت تغییر ویژگی‌ها
            var attributeOptions = document.querySelectorAll('.widget-attribute-option[data-widget-id="' + widgetId + '"]');
            attributeOptions.forEach(function(option) {
                option.addEventListener('click', function() {
                    if (widget && widget.classList.contains('out-of-stock')) return;
                    
                    var group = this.closest('.widget-attribute-group');
                    if (group) {
                        group.querySelectorAll('.widget-attribute-option').forEach(function(opt) {
                            opt.classList.remove('selected');
                        });
                    }
                    
                    this.classList.add('selected');
                    updateVariationPrice(widgetId, availableVariations);
                });
            });
            
            // به‌روزرسانی خودکار قیمت برای گزینه پیش‌فرض
            if (widget && widget.querySelector('.widget-attribute-option.selected')) {
                updateVariationPrice(widgetId, availableVariations);
            }
            
            // مقداردهی اولیه دکمه‌های تعداد
            updateQuantityButtons();
        });

        function updateVariationPrice(wid, availableVariations) {
            var widget = document.querySelector('.custom-product-widget[data-widget-id="' + wid + '"]');
            var priceElement = document.getElementById('widget-price-' + wid);
            var quantityInput = document.querySelector('.widget-quantity-input[data-widget-id="' + wid + '"]');
            var quantitySelector = document.querySelector('.widget-quantity-selector[data-widget-id="' + wid + '"]');
            var addToCartBtn = document.querySelector('.widget-add-to-cart-btn[data-widget-id="' + wid + '"]');
            
            if (!priceElement || !widget) return;
            
            var priceContainer = priceElement.parentElement;
            var selectedAttributes = {};
            
            widget.querySelectorAll('.widget-attribute-option.selected').forEach(function(option) {
                if (option.dataset.attribute && option.dataset.value) {
                    selectedAttributes[option.dataset.attribute] = option.dataset.value;
                }
            });

            var matchedVariation = null;
            for (var i = 0; i < availableVariations.length; i++) {
                var variation = availableVariations[i];
                var isMatch = true;
                var matchCount = 0;
                
                for (var attr in selectedAttributes) {
                    if (variation.attributes[attr]) {
                        if (variation.attributes[attr] === selectedAttributes[attr] || variation.attributes[attr] === '') {
                            matchCount++;
                        } else {
                            isMatch = false;
                            break;
                        }
                    }
                }
                
                if (isMatch && matchCount > 0) {
                    matchedVariation = variation;
                    break;
                }
            }

            if (matchedVariation && priceElement) {
                priceContainer.classList.add('updating');
                
                // به‌روزرسانی موجودی و حداکثر تعداد
                var maxQty = 9999;
                var stockManaged = false;
                
                if (matchedVariation.is_in_stock) {
                    if (matchedVariation.max_qty !== null && matchedVariation.max_qty !== '' && matchedVariation.max_qty > 0) {
                        maxQty = parseInt(matchedVariation.max_qty);
                        stockManaged = true;
                    }
                } else {
                    maxQty = 0;
                }
                
                widget.dataset.maxQuantity = maxQty;
                widget.dataset.manageStock = stockManaged ? '1' : '0';
                
                if (quantityInput) {
                    quantityInput.setAttribute('max', maxQty);
                    var currentQty = parseInt(quantityInput.value) || 1;
                    
                    if (currentQty > maxQty) {
                        quantityInput.value = Math.max(1, maxQty);
                    }
                    
                    var decreaseBtn = widget.querySelector('.widget-quantity-decrease');
                    var increaseBtn = widget.querySelector('.widget-quantity-increase');
                    
                    if (decreaseBtn) {
                        decreaseBtn.disabled = parseInt(quantityInput.value) <= 1;
                    }
                    if (increaseBtn) {
                        increaseBtn.disabled = parseInt(quantityInput.value) >= maxQty;
                    }
                }
                
                var regularPrice = parseFloat(matchedVariation.display_regular_price) || 0;
                var salePrice = parseFloat(matchedVariation.display_price) || 0;
                var isOnSale = salePrice > 0 && regularPrice > 0 && salePrice < regularPrice;
                var hasValidPrice = false;
                var isInStock = matchedVariation.is_in_stock;
                
                // انیمیشن تغییر قیمت
                setTimeout(function() {
                    if (isOnSale) {
                        var discountPercentage = Math.round(((regularPrice - salePrice) / regularPrice) * 100);
                        
                        priceElement.innerHTML = '<div class="widget-price-wrapper">' +
                            '<div class="widget-regular-price" data-target="' + Math.round(regularPrice) + '">۰' +
                            '<span class="widget-currency">تومان</span></div>' +
                            '<div class="widget-sale-price" data-target="' + Math.round(salePrice) + '">۰' +
                            '<span class="widget-currency">تومان</span></div>' +
                            '<div class="widget-discount-badge">' +
                            convertToPersianNumber(discountPercentage) + '% تخفیف</div>' +
                            '</div>';
                        
                        // انیمیشن شمارشگر برای قیمت اصلی
                        animatePrice(priceElement.querySelector('.widget-regular-price'), Math.round(regularPrice), function() {
                            priceElement.querySelector('.widget-regular-price').classList.add('show');
                        });
                        
                        // انیمیشن شمارشگر برای قیمت تخفیف با تاخیر
                        setTimeout(function() {
                            animatePrice(priceElement.querySelector('.widget-sale-price'), Math.round(salePrice), function() {
                                priceElement.querySelector('.widget-sale-price').classList.add('show');
                            });
                        }, 200);
                        
                        // انیمیشن بج تخفیف با تاخیر بیشتر
                        setTimeout(function() {
                            var badge = priceElement.querySelector('.widget-discount-badge');
                            if (badge) badge.classList.add('show');
                        }, 500);
                        
                        hasValidPrice = true;
                    } else {
                        var displayPrice = salePrice > 0 ? salePrice : regularPrice;
                        if (displayPrice > 0) {
                            priceElement.innerHTML = '<div class="widget-price" data-target="' + Math.round(displayPrice) + '">۰' +
                                '<span class="widget-currency">تومان</span></div>';
                            
                            // انیمیشن شمارشگر برای قیمت معمولی
                            animatePrice(priceElement.querySelector('.widget-price'), Math.round(displayPrice), function() {
                                priceElement.querySelector('.widget-price').classList.add('price-changing');
                                setTimeout(function() {
                                    var el = priceElement.querySelector('.widget-price');
                                    if (el) el.classList.remove('price-changing');
                                }, 500);
                            });
                            
                            hasValidPrice = true;
                        } else {
                            priceElement.innerHTML = '<div class="widget-price">قیمت نامشخص</div>';
                        }
                    }
                    
                    priceContainer.classList.remove('updating');
                    widget.dataset.currentVariationId = matchedVariation.variation_id;
                    widget.dataset.hasPrice = hasValidPrice ? '1' : '0';
                    widget.dataset.inStock = isInStock ? '1' : '0';
                    
                    // نمایش یا مخفی کردن بخش سبد خرید
                    if (!hasValidPrice || !isInStock || maxQty <= 0) {
                        if (addToCartBtn) addToCartBtn.classList.add('hidden');
                        if (quantitySelector) quantitySelector.classList.add('hidden');
                    } else {
                        var currentQty = quantityInput ? parseInt(quantityInput.value) : 1;
                        if (currentQty <= maxQty) {
                            if (addToCartBtn) addToCartBtn.classList.remove('hidden');
                            if (quantitySelector) quantitySelector.classList.remove('hidden');
                        }
                    }
                    
                    // به‌روزرسانی پیام موجودی
                    var stockInfo = widget.querySelector('.widget-stock-info');
                    if (stockInfo) stockInfo.remove();
                    
                    if (isInStock && stockManaged && maxQty > 0 && maxQty <= 5) {
                        var newStockInfo = document.createElement('div');
                        newStockInfo.className = 'widget-stock-info low-stock';
                        newStockInfo.textContent = 'تنها ' + convertToPersianNumber(maxQty) + ' عدد در انبار باقی مانده';
                        widget.querySelector('.widget-cart-section').appendChild(newStockInfo);
                    }
                }, 100);
            }
        }

        // تابع انیمیشن شمارشگر قیمت
        function animatePrice(element, targetPrice, callback) {
            if (!element) return;
            
            var duration = 100; // مدت زمان انیمیشن به میلی‌ثانیه
            var steps = 40; // تعداد مراحل انیمیشن
            var stepDuration = duration / steps;
            var currentStep = 0;
            var startPrice = 0;
            var increment = targetPrice / steps;
            
            var currencySpan = element.querySelector('.widget-currency');
            var currencyText = currencySpan ? currencySpan.outerHTML : '';
            
            var interval = setInterval(function() {
                currentStep++;
                var currentPrice = Math.round(startPrice + (increment * currentStep));
                
                // اطمینان از رسیدن به قیمت نهایی
                if (currentStep >= steps) {
                    currentPrice = targetPrice;
                    clearInterval(interval);
                    if (callback) callback();
                }
                
                var formattedPrice = convertToPersianNumber(currentPrice.toLocaleString('en-US'));
                element.innerHTML = formattedPrice + currencyText;
            }, stepDuration);
        }

        // رویداد کلیک دکمه افزودن به سبد
        var addToCartBtn = document.querySelector('.widget-add-to-cart-btn[data-widget-id="' + widgetId + '"]');
        if (addToCartBtn) {
            addToCartBtn.addEventListener('click', function() {
                var widget = this.closest('.custom-product-widget');
                if (!widget) return;
                
                var button = this;
                var variationId = widget.dataset.currentVariationId || 0;
                var quantityInput = document.querySelector('.widget-quantity-input[data-widget-id="' + widgetId + '"]');
                var quantity = quantityInput ? parseInt(quantityInput.value) || 1 : 1;
                var maxQuantity = parseInt(widget.dataset.maxQuantity) || 9999;
                
                if (button.disabled) return;
                
                // بررسی تعداد با موجودی
                if (quantity > maxQuantity) {
                    alert('تعداد درخواستی بیشتر از موجودی است. حداکثر ' + convertToPersianNumber(maxQuantity) + ' عدد موجود است.');
                    if (quantityInput) quantityInput.value = maxQuantity;
                    return;
                }
                
                var selectedAttributes = {};
                widget.querySelectorAll('.widget-attribute-option.selected').forEach(function(option) {
                    if (option.dataset.attribute && option.dataset.value) {
                        selectedAttributes[option.dataset.attribute] = option.dataset.value;
                    }
                });

                var hasVariations = widget.querySelector('.widget-attributes-section');
                if (hasVariations && Object.keys(selectedAttributes).length === 0) {
                    alert('لطفاً ویژگی‌های محصول را انتخاب کنید');
                    return;
                }

                button.classList.add('loading');

                if (typeof jQuery === 'undefined') {
                    console.error('jQuery is not loaded');
                    button.classList.remove('loading');
                    alert('خطا در بارگذاری سیستم');
                    return;
                }

                jQuery.ajax({
                    url: '<?php echo esc_url(admin_url('admin-ajax.php')); ?>',
                    type: 'POST',
                    data: {
                        action: 'custom_add_to_cart',
                        product_id: productId,
                        variation_id: variationId,
                        quantity: quantity,
                        variation: selectedAttributes,
                        nonce: '<?php echo wp_create_nonce('add_to_cart_nonce'); ?>'
                    },
                    success: function(response) {
                        button.classList.remove('loading');
                        
                        if (response.success) {
                            showSuccessMessage(widgetId, response.data);
                            jQuery('body').trigger('wc_fragment_refresh');
                            jQuery('body').trigger('added_to_cart', [response.data.cart_hash, jQuery(button)]);
                        } else {
                            alert(response.data || 'خطا در افزودن به سبد خرید');
                        }
                    },
                    error: function(xhr, status, error) {
                        button.classList.remove('loading');
                        console.error('AJAX Error:', error);
                        var errorMessage = 'خطا در ارتباط با سرور';
                        if (xhr.responseJSON && xhr.responseJSON.data) {
                            errorMessage = xhr.responseJSON.data;
                        }
                        alert(errorMessage);
                    }
                });
            });
        }
        
        function showSuccessMessage(wid, data) {
            var successMessage = document.getElementById('widget-success-message-' + wid);
            if (!successMessage) return;
            
            if (data && data.message) {
                var messageHTML = '<div><strong>' + data.message + '</strong>';
                if (data.cart_count) {
                    messageHTML += '<br><small>تعداد کل: ' + convertToPersianNumber(data.cart_count) + '</small>';
                }
                if (data.cart_url) {
                    messageHTML += ' <a href="' + data.cart_url + '">مشاهده سبد</a>';
                }
                messageHTML += '</div>';
                successMessage.innerHTML = messageHTML;
            }
            
            successMessage.classList.add('show');
            
            setTimeout(function() {
                successMessage.classList.remove('show');
            }, 5000);
        }
        
        function convertToPersianNumber(num) {
            var persianNumbers = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'];
            var numString = num.toString();
            var result = '';
            for (var i = 0; i < numString.length; i++) {
                var char = numString[i];
                if (char >= '0' && char <= '9') {
                    result += persianNumbers[parseInt(char)];
                } else {
                    result += char;
                }
            }
            return result;
        }
    })();
    </script>
    
<?php
    return ob_get_clean();
}

// هندلر AJAX برای افزودن به سبد خرید
add_action('wp_ajax_custom_add_to_cart', 'handle_custom_add_to_cart');
add_action('wp_ajax_nopriv_custom_add_to_cart', 'handle_custom_add_to_cart');

function handle_custom_add_to_cart() {
    try {
        if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'add_to_cart_nonce')) {
            wp_send_json_error('خطای امنیتی');
            return;
        }
        
        $product_id = isset($_POST['product_id']) ? intval($_POST['product_id']) : 0;
        $variation_id = isset($_POST['variation_id']) ? intval($_POST['variation_id']) : 0;
        $quantity = isset($_POST['quantity']) ? intval($_POST['quantity']) : 1;
        $variation = isset($_POST['variation']) ? $_POST['variation'] : array();
        
        if ($product_id <= 0) {
            wp_send_json_error('شناسه محصول نامعتبر است');
            return;
        }
        
        if ($quantity <= 0) {
            $quantity = 1;
        }
        
        $product = wc_get_product($product_id);
        
        if (!$product) {
            wp_send_json_error('محصول یافت نشد');
            return;
        }
        
        if (!$product->is_in_stock()) {
            wp_send_json_error('محصول موجود نمی‌باشد');
            return;
        }
        
        // بررسی موجودی برای محصول متغیر
        if ($variation_id) {
            $variation_product = wc_get_product($variation_id);
            if (!$variation_product || !$variation_product->is_in_stock()) {
                wp_send_json_error('این ویژگی محصول موجود نمی‌باشد');
                return;
            }
            
            // بررسی تعداد با موجودی
            if ($variation_product->managing_stock()) {
                $stock_quantity = $variation_product->get_stock_quantity();
                if ($stock_quantity !== null && $quantity > $stock_quantity) {
                    wp_send_json_error('تعداد درخواستی بیشتر از موجودی است. حداکثر ' . $stock_quantity . ' عدد موجود است.');
                    return;
                }
            }
        } else {
            // بررسی تعداد برای محصول ساده
            if ($product->managing_stock()) {
                $stock_quantity = $product->get_stock_quantity();
                if ($stock_quantity !== null && $quantity > $stock_quantity) {
                    wp_send_json_error('تعداد درخواستی بیشتر از موجودی است. حداکثر ' . $stock_quantity . ' عدد موجود است.');
                    return;
                }
            }
        }
        
        if ($product->is_type('variable') && !$variation_id && !empty($variation)) {
            $available_variations = $product->get_available_variations();
            
            foreach ($available_variations as $var) {
                $match = true;
                foreach ($variation as $attr_name => $attr_value) {
                    if (!isset($var['attributes'][$attr_name]) || 
                        $var['attributes'][$attr_name] !== $attr_value) {
                        $match = false;
                        break;
                    }
                }
                if ($match) {
                    $variation_id = $var['variation_id'];
                    break;
                }
            }
        }
        
        $formatted_variation = array();
        if (!empty($variation)) {
            foreach ($variation as $key => $value) {
                $formatted_variation[$key] = $value;
            }
        }
        
        $added = WC()->cart->add_to_cart($product_id, $quantity, $variation_id, $formatted_variation);
        
        if ($added) {
            $cart_count = WC()->cart->get_cart_contents_count();
            $cart_total = WC()->cart->get_cart_total();
            $added_product = wc_get_product($variation_id ? $variation_id : $product_id);
            $product_name = $added_product ? $added_product->get_name() : 'محصول';
            $cart_url = wc_get_cart_url();
            
            wp_send_json_success(array(
                'message' => sprintf('"%s" با موفقیت به سبد خرید اضافه شد', $product_name),
                'cart_count' => $cart_count,
                'cart_total' => $cart_total,
                'cart_url' => $cart_url,
                'product_name' => $product_name,
                'quantity' => $quantity,
                'cart_hash' => WC()->cart->get_cart_hash()
            ));
        } else {
            $notices = wc_get_notices('error');
            $error_message = 'خطا در افزودن محصول به سبد خرید';
            
            if (!empty($notices)) {
                $error_message = implode(', ', array_column($notices, 'notice'));
                wc_clear_notices();
            }
            
            wp_send_json_error($error_message);
        }
    } catch (Exception $e) {
        wp_send_json_error('خطای سیستمی: ' . $e->getMessage());
    }
}

// شورت‌کد برای استفاده آسان
add_shortcode('product_widget', function($atts) {
    global $product, $post;
    
    $atts = shortcode_atts(array(
        'id' => null
    ), $atts);
    
    $product_id = $atts['id'];
    
    if (!$product_id) {
        if (is_product() && $product) {
            $product_id = $product->get_id();
        }
        elseif (isset($GLOBALS['product']) && is_object($GLOBALS['product'])) {
            $product_id = $GLOBALS['product']->get_id();
        }
        elseif ($post && $post->post_type === 'product') {
            $product_id = $post->ID;
        }
        elseif (get_query_var('product')) {
            $product_slug = get_query_var('product');
            $product_post = get_page_by_path($product_slug, OBJECT, 'product');
            if ($product_post) {
                $product_id = $product_post->ID;
            }
        }
    }
    
    return custom_product_widget($product_id);
});

				
			

در ادامه این شرت کد و در جای مد نظر در قالب محصول قرار دهید :

				
					[product_widget]

				
			

اگه برای متغییر های مختلف تصاویر متفاوتی دارید و برای هر متغییر ٬ تصویر شاخص ست کردید برای نمایش بدردستی این تصاویر از این کد استفاده کنید در فاکشن های سایت

				
					/**
 * شورت‌کد نمایش تصاویر محصول WooCommerce - نسخه بهبود یافته
 * نسخه: 2.0
 * 
 * نحوه استفاده:
 * [product_images] یا [product_images id="123"]
 * 
 * این کد را در functions.php قرار دهید
 */

// جلوگیری از دسترسی مستقیم
if (!defined('ABSPATH')) {
    exit;
}

/**
 * تابع اصلی نمایش تصاویر محصول
 */
function custom_product_images($product_id = null) {
    global $product;
    
    // ایجاد ID یکتا برای هر گالری
    static $gallery_counter = 0;
    $gallery_counter++;
    $gallery_id = 'gallery-' . $gallery_counter . '-' . time();
    
    // دریافت محصول
    if (!$product_id && is_product()) {
        $current_product = $product;
    } elseif ($product_id) {
        $current_product = wc_get_product($product_id);
    } else {
        return '<p style="color: #dc2626; text-align: center; padding: 20px;">محصولی یافت نشد</p>';
    }
    
    if (!$current_product || !is_object($current_product)) {
        return '<p style="color: #dc2626; text-align: center; padding: 20px;">محصول معتبر نیست</p>';
    }
    
    // دریافت اطلاعات تصاویر
    $product_image_id = $current_product->get_image_id();
    $gallery_image_ids = $current_product->get_gallery_image_ids();
    $is_variable = $current_product->is_type('variable');
    
    // ترکیب تصویر اصلی با گالری
    $all_image_ids = array();
    if ($product_image_id) {
        $all_image_ids[] = $product_image_id;
    }
    if (!empty($gallery_image_ids)) {
        $all_image_ids = array_merge($all_image_ids, $gallery_image_ids);
    }
    
    // حذف تکراری‌ها
    $all_image_ids = array_unique($all_image_ids);
    
    if (empty($all_image_ids)) {
        return '<p style="text-align: center; padding: 40px; color: #9ca3af;">تصویری برای این محصول وجود ندارد</p>';
    }
    
    // دریافت تصاویر متغیرها برای محصولات متغیر
    $variation_images = array();
    $variation_attributes_map = array();
    
    if ($is_variable) {
        $available_variations = $current_product->get_available_variations();
        foreach ($available_variations as $variation) {
            $variation_id = $variation['variation_id'];
            
            if (!empty($variation['image_id'])) {
                $variation_images[$variation_id] = array(
                    'image_id' => $variation['image_id'],
                    'image_url' => wp_get_attachment_image_url($variation['image_id'], 'large'),
                    'thumb_url' => wp_get_attachment_image_url($variation['image_id'], 'thumbnail'),
                    'attributes' => $variation['attributes']
                );
                
                // ایجاد کلید یکتا برای هر ترکیب ویژگی
                $attr_key = serialize($variation['attributes']);
                $variation_attributes_map[$attr_key] = $variation_id;
            }
        }
    }
    
    ob_start();
    ?>
    
    <style>
        .product-images-gallery {
            width: 100%;
            max-width: 600px;
            margin: 0 auto 30px;
            direction: rtl;
            font-family: 'shabnam';
        }
        
        .gallery-main-image-container {
            position: relative;
            width: 100%;
            padding-bottom: 100%;
            background: #f8fafc;
            border-radius: 16px;
            overflow: hidden;
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
            margin-bottom: 16px;
        }
        
        .gallery-main-image {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            object-fit: cover;
            transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
        }
        
        .gallery-main-image.fade-out {
            opacity: 0;
            transform: scale(0.95);
        }
        
        .gallery-main-image.fade-in {
            opacity: 1;
            transform: scale(1);
        }
        
        .gallery-zoom-icon {
            position: absolute;
            top: 16px;
            left: 16px;
            background: rgba(255, 255, 255, 0.95);
            width: 40px;
            height: 40px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            transition: all 0.3s ease;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
            z-index: 10;
        }
        
        .gallery-zoom-icon:hover {
            background: white;
            transform: scale(1.1);
        }
        
        .gallery-zoom-icon svg {
            width: 20px;
            height: 20px;
            stroke: #374151;
        }
        
        .gallery-thumbnails {
            display: flex;
            gap: 8px;
            overflow-x: auto;
            padding: 8px 4px;
            scrollbar-width: thin;
            scrollbar-color: #e5e7eb transparent;
        }
        
        .gallery-thumbnails::-webkit-scrollbar {
            height: 6px;
        }
        
        .gallery-thumbnails::-webkit-scrollbar-track {
            background: transparent;
        }
        
        .gallery-thumbnails::-webkit-scrollbar-thumb {
            background: #e5e7eb;
            border-radius: 3px;
        }
        
        .gallery-thumbnails::-webkit-scrollbar-thumb:hover {
            background: #d1d5db;
        }
        
        .gallery-thumbnail {
            position: relative;
            min-width: 70px;
            width: 70px;
            height: 70px;
            border-radius: 10px;
            overflow: hidden;
            cursor: pointer;
            border: 2px solid transparent;
            transition: all 0.3s ease;
            flex-shrink: 0;
        }
        
        .gallery-thumbnail:hover {
            border-color: #F85811;
            transform: translateY(-2px);
        }
        
        .gallery-thumbnail.active {
            border-color: #1f2937;
            box-shadow: 0 4px 12px rgba(31, 41, 55, 0.3);
        }
        
        .gallery-thumbnail img {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }
        
        /* مودال تصویر بزرگ */
        .gallery-lightbox {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0, 0, 0, 0.95);
            z-index: 99999;
            opacity: 0;
            transition: opacity 0.3s ease;
        }
        
        .gallery-lightbox.active {
            display: flex;
            align-items: center;
            justify-content: center;
            opacity: 1;
        }
        
        .gallery-lightbox-content {
            position: relative;
            max-width: 90%;
            max-height: 90%;
            transform: scale(0.9);
            transition: transform 0.3s ease;
        }
        
        .gallery-lightbox.active .gallery-lightbox-content {
            transform: scale(1);
        }
        
        .gallery-lightbox-image {
            max-width: 100%;
            max-height: 90vh;
            object-fit: contain;
            border-radius: 8px;
        }
        
        .gallery-lightbox-close {
            position: absolute;
            top: -50px;
            left: 0;
            background: white;
            width: 40px;
            height: 40px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            transition: all 0.3s ease;
        }
        
        .gallery-lightbox-close:hover {
            background: #f3f4f6;
            transform: rotate(90deg);
        }
        
        .gallery-lightbox-close svg {
            width: 24px;
            height: 24px;
            stroke: #1f2937;
        }
        
        .gallery-lightbox-nav {
            position: absolute;
            top: 50%;
            transform: translateY(-50%);
            background: rgba(255, 255, 255, 0.95);
            width: 50px;
            height: 50px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            transition: all 0.3s ease;
        }
        
        .gallery-lightbox-nav:hover {
            background: white;
            transform: translateY(-50%) scale(1.1);
        }
        
        .gallery-lightbox-nav.prev {
            right: -70px;
        }
        
        .gallery-lightbox-nav.next {
            left: -70px;
        }
        
        .gallery-lightbox-nav svg {
            width: 24px;
            height: 24px;
            stroke: #1f2937;
        }
        
        .gallery-loading-overlay {
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(248, 250, 252, 0.8);
            display: none;
            align-items: center;
            justify-content: center;
            border-radius: 16px;
            z-index: 5;
        }
        
        .gallery-loading-overlay.active {
            display: flex;
        }
        
        .gallery-spinner {
            width: 40px;
            height: 40px;
            border: 4px solid #e5e7eb;
            border-top: 4px solid #F85811;
            border-radius: 50%;
            animation: gallery-spin 1s linear infinite;
        }
        
        @keyframes gallery-spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
        
        /* تبلت */
        @media (max-width: 768px) {
            .product-images-gallery {
                max-width: 100%;
            }
            
            .gallery-main-image-container {
                border-radius: 12px;
                margin-bottom: 12px;
            }
            
            .gallery-thumbnail {
                min-width: 60px;
                width: 60px;
                height: 60px;
                border-radius: 8px;
            }
            
            .gallery-thumbnails {
                gap: 6px;
            }
            
            .gallery-lightbox-nav {
                width: 40px;
                height: 40px;
            }
            
            .gallery-lightbox-nav.prev {
                right: 10px;
            }
            
            .gallery-lightbox-nav.next {
                left: 10px;
            }
        }
        
        /* موبایل */
        @media (max-width: 480px) {
            .product-images-gallery {
                max-width: 100%;
                margin: 0 0 20px;
            }
            
            .gallery-main-image-container {
                border-radius: 8px;
                margin-bottom: 10px;
                padding-bottom: 100%;
            }
            
            .gallery-zoom-icon {
                width: 35px;
                height: 35px;
                top: 12px;
                left: 12px;
            }
            
            .gallery-zoom-icon svg {
                width: 18px;
                height: 18px;
            }
            
            .gallery-thumbnails {
                gap: 6px;
                padding: 6px 2px;
            }
            
            .gallery-thumbnail {
                min-width: 50px;
                width: 50px;
                height: 50px;
                border-radius: 6px;
                border-width: 2px;
            }
            
            .gallery-lightbox-content {
                max-width: 95%;
            }
            
            .gallery-lightbox-close {
                top: -45px;
                width: 35px;
                height: 35px;
            }
            
            .gallery-lightbox-nav {
                width: 35px;
                height: 35px;
            }
            
            .gallery-lightbox-nav.prev {
                right: 5px;
            }
            
            .gallery-lightbox-nav.next {
                left: 5px;
            }
        }
    </style>
    
    <div class="product-images-gallery" 
         data-gallery-id="<?php echo esc_attr($gallery_id); ?>"
         data-product-id="<?php echo esc_attr($current_product->get_id()); ?>"
         data-is-variable="<?php echo $is_variable ? '1' : '0'; ?>">
        
        <!-- تصویر اصلی -->
        <div class="gallery-main-image-container">
            <div class="gallery-loading-overlay">
                <div class="gallery-spinner"></div>
            </div>
            
            <div class="gallery-zoom-icon" title="بزرگنمایی">
                <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
                          d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v6m3-3H7"/>
                </svg>
            </div>
            
            <?php
            $first_image_id = reset($all_image_ids);
            $first_image_url = wp_get_attachment_image_url($first_image_id, 'large');
            $first_image_alt = get_post_meta($first_image_id, '_wp_attachment_image_alt', true);
            ?>
            
            <img decoding="async" src="<?php echo esc_url($first_image_url); ?>" 
                 alt="<?php echo esc_attr($first_image_alt ?: $current_product->get_name()); ?>"
                 class="gallery-main-image fade-in"
                 data-current-index="0">
        </div>
        
        <!-- تصاویر کوچک -->
        <?php if (count($all_image_ids) > 1): ?>
        <div class="gallery-thumbnails">
            <?php foreach ($all_image_ids as $index => $image_id): 
                $thumb_url = wp_get_attachment_image_url($image_id, 'thumbnail');
                $thumb_alt = get_post_meta($image_id, '_wp_attachment_image_alt', true);
            ?>
            <div class="gallery-thumbnail <?php echo $index === 0 ? 'active' : ''; ?>" 
                 data-index="<?php echo esc_attr($index); ?>"
                 data-image-id="<?php echo esc_attr($image_id); ?>"
                 data-large-url="<?php echo esc_url(wp_get_attachment_image_url($image_id, 'large')); ?>">
                <img decoding="async" src="<?php echo esc_url($thumb_url); ?>" 
                     alt="<?php echo esc_attr($thumb_alt ?: $current_product->get_name()); ?>">
            </div>
            <?php endforeach; ?>
        </div>
        <?php endif; ?>
        
        <!-- داده‌های تصاویر متغیرها -->
        <?php if ($is_variable && !empty($variation_images)): ?>
        <script type="application/json" class="variation-images-data">
            <?php echo wp_json_encode($variation_images); ?>
        </script>
        <script type="application/json" class="variation-attributes-map">
            <?php echo wp_json_encode($variation_attributes_map); ?>
        </script>
        <?php endif; ?>
    </div>
    
    <!-- مودال بزرگنمایی -->
    <div class="gallery-lightbox" id="lightbox-<?php echo esc_attr($gallery_id); ?>">
        <div class="gallery-lightbox-content">
            <div class="gallery-lightbox-close">
                <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
                </svg>
            </div>
            
            <?php if (count($all_image_ids) > 1): ?>
            <div class="gallery-lightbox-nav prev">
                <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/>
                </svg>
            </div>
            <div class="gallery-lightbox-nav next">
                <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/>
                </svg>
            </div>
            <?php endif; ?>
            
            <img decoding="async" src="" alt="" class="gallery-lightbox-image" title="باکس افزودن به سبد خرید حرفه ای برای محصولات متغییر + کد رایگان همراه با آموزش 1">
        </div>
    </div>
    
    <script type="pmdelayedscript" data-cfasync="false" data-no-optimize="1" data-no-defer="1" data-no-minify="1" data-rocketlazyloadscript="1">
    (function() {
        'use strict';
        
        var galleryId = '<?php echo esc_js($gallery_id); ?>';
        var productId = <?php echo esc_js($current_product->get_id()); ?>;
        
        document.addEventListener('DOMContentLoaded', function() {
            var gallery = document.querySelector('.product-images-gallery[data-gallery-id="' + galleryId + '"]');
            if (!gallery) return;
            
            var mainImage = gallery.querySelector('.gallery-main-image');
            var thumbnails = gallery.querySelectorAll('.gallery-thumbnail');
            var zoomIcon = gallery.querySelector('.gallery-zoom-icon');
            var lightbox = document.getElementById('lightbox-' + galleryId);
            var lightboxImage = lightbox ? lightbox.querySelector('.gallery-lightbox-image') : null;
            var lightboxClose = lightbox ? lightbox.querySelector('.gallery-lightbox-close') : null;
            var lightboxPrev = lightbox ? lightbox.querySelector('.gallery-lightbox-nav.prev') : null;
            var lightboxNext = lightbox ? lightbox.querySelector('.gallery-lightbox-nav.next') : null;
            var loadingOverlay = gallery.querySelector('.gallery-loading-overlay');
            
            var isVariable = gallery.dataset.isVariable === '1';
            var variationImagesData = {};
            var variationAttributesMap = {};
            
            // خواندن داده‌های تصاویر متغیرها
            if (isVariable) {
                var variationDataEl = gallery.querySelector('.variation-images-data');
                if (variationDataEl) {
                    try {
                        variationImagesData = JSON.parse(variationDataEl.textContent);
                    } catch (e) {
                        console.error('خطا در خواندن داده‌های تصاویر متغیرها:', e);
                    }
                }
                
                var attributesMapEl = gallery.querySelector('.variation-attributes-map');
                if (attributesMapEl) {
                    try {
                        variationAttributesMap = JSON.parse(attributesMapEl.textContent);
                    } catch (e) {
                        console.error('خطا در خواندن نقشه ویژگی‌ها:', e);
                    }
                }
            }
            
            // کلیک روی تصاویر کوچک
            thumbnails.forEach(function(thumbnail) {
                thumbnail.addEventListener('click', function() {
                    var index = parseInt(this.dataset.index);
                    var largeUrl = this.dataset.largeUrl;
                    changeMainImage(largeUrl, index);
                });
            });
            
            // تابع تغییر تصویر اصلی
            function changeMainImage(url, index) {
                if (!mainImage || !url) return;
                
                mainImage.classList.remove('fade-in');
                mainImage.classList.add('fade-out');
                
                setTimeout(function() {
                    mainImage.src = url;
                    mainImage.dataset.currentIndex = index;
                    mainImage.classList.remove('fade-out');
                    mainImage.classList.add('fade-in');
                    
                    // به‌روزرسانی thumbnail فعال
                    thumbnails.forEach(function(thumb) {
                        thumb.classList.remove('active');
                    });
                    var activeThumbnail = gallery.querySelector('.gallery-thumbnail[data-index="' + index + '"]');
                    if (activeThumbnail) {
                        activeThumbnail.classList.add('active');
                    }
                }, 250);
            }
            
            // بزرگنمایی تصویر
            if (zoomIcon && lightbox && lightboxImage) {
                zoomIcon.addEventListener('click', function() {
                    lightboxImage.src = mainImage.src;
                    lightboxImage.alt = mainImage.alt;
                    lightbox.classList.add('active');
                    document.body.style.overflow = 'hidden';
                });
                
                if (lightboxClose) {
                    lightboxClose.addEventListener('click', closeLightbox);
                }
                
                lightbox.addEventListener('click', function(e) {
                    if (e.target === lightbox) {
                        closeLightbox();
                    }
                });
                
                // دکمه‌های قبلی/بعدی
                if (lightboxPrev && thumbnails.length > 1) {
                    lightboxPrev.addEventListener('click', function() {
                        var currentIndex = parseInt(mainImage.dataset.currentIndex);
                        var prevIndex = currentIndex > 0 ? currentIndex - 1 : thumbnails.length - 1;
                        var prevThumbnail = gallery.querySelector('.gallery-thumbnail[data-index="' + prevIndex + '"]');
                        if (prevThumbnail) {
                            var prevUrl = prevThumbnail.dataset.largeUrl;
                            changeMainImage(prevUrl, prevIndex);
                            lightboxImage.src = prevUrl;
                        }
                    });
                }
                
                if (lightboxNext && thumbnails.length > 1) {
                    lightboxNext.addEventListener('click', function() {
                        var currentIndex = parseInt(mainImage.dataset.currentIndex);
                        var nextIndex = currentIndex < thumbnails.length - 1 ? currentIndex + 1 : 0;
                        var nextThumbnail = gallery.querySelector('.gallery-thumbnail[data-index="' + nextIndex + '"]');
                        if (nextThumbnail) {
                            var nextUrl = nextThumbnail.dataset.largeUrl;
                            changeMainImage(nextUrl, nextIndex);
                            lightboxImage.src = nextUrl;
                        }
                    });
                }
                
                // کلید ESC برای بستن
                document.addEventListener('keydown', function(e) {
                    if (e.key === 'Escape' && lightbox.classList.contains('active')) {
                        closeLightbox();
                    }
                });
            }
            
            function closeLightbox() {
                if (lightbox) {
                    lightbox.classList.remove('active');
                    document.body.style.overflow = '';
                }
            }
            
            // گوش دادن به تغییرات ویژگی‌ها برای محصولات متغیر
            if (isVariable && Object.keys(variationImagesData).length > 0) {
                // پیدا کردن ویجت محصول
                var widgets = document.querySelectorAll('.custom-product-widget[data-product-id="' + productId + '"]');
                
                widgets.forEach(function(widget) {
                    // گوش دادن به کلیک روی گزینه‌های ویژگی
                    widget.addEventListener('click', function(e) {
                        if (e.target.classList.contains('widget-attribute-option')) {
                            setTimeout(function() {
                                updateImageForVariation(widget);
                            }, 100);
                        }
                    });
                });
                
                // بررسی اولیه برای ویژگی‌های پیش‌فرض
                if (widgets.length > 0) {
                    setTimeout(function() {
                        updateImageForVariation(widgets[0]);
                    }, 300);
                }
            }
            
            function updateImageForVariation(widget) {
                if (!widget) return;
                
                // جمع‌آوری ویژگی‌های انتخاب شده
                var selectedAttributes = {};
                var selectedOptions = widget.querySelectorAll('.widget-attribute-option.selected');
                
                selectedOptions.forEach(function(option) {
                    var attrName = option.dataset.attribute;
                    var attrValue = option.dataset.value;
                    if (attrName && attrValue) {
                        selectedAttributes[attrName] = attrValue;
                    }
                });
                
                // اگر هیچ ویژگی انتخاب نشده، خروج
                if (Object.keys(selectedAttributes).length === 0) return;
                
                // پیدا کردن متغیر مطابق
                var matchedVariationId = null;
                
                for (var varId in variationImagesData) {
                    var variation = variationImagesData[varId];
                    var isMatch = true;
                    
                    for (var attrKey in selectedAttributes) {
                        var selectedValue = selectedAttributes[attrKey];
                        var varValue = variation.attributes[attrKey];
                        
                        // بررسی تطابق (varValue می‌تواند خالی باشد برای "هر مقداری")
                        if (varValue && varValue !== '' && varValue !== selectedValue) {
                            isMatch = false;
                            break;
                        }
                    }
                    
                    if (isMatch) {
                        matchedVariationId = varId;
                        break;
                    }
                }
                
                // اگر متغیر پیدا شد و تصویر دارد، آپدیت کن
                if (matchedVariationId && variationImagesData[matchedVariationId]) {
                    var variationData = variationImagesData[matchedVariationId];
                    var variationImageId = variationData.image_id;
                    var variationImageUrl = variationData.image_url;
                    
                    if (variationImageUrl) {
                        // نمایش loading
                        if (loadingOverlay) {
                            loadingOverlay.classList.add('active');
                        }
                        
                        setTimeout(function() {
                            // پیدا کردن thumbnail مربوط به این تصویر
                            var targetThumbnail = gallery.querySelector('.gallery-thumbnail[data-image-id="' + variationImageId + '"]');
                            var targetIndex = 0;
                            
                            if (targetThumbnail) {
                                targetIndex = parseInt(targetThumbnail.dataset.index);
                            }
                            
                            // تغییر تصویر اصلی
                            changeMainImage(variationImageUrl, targetIndex);
                            
                            // پنهان کردن loading
                            if (loadingOverlay) {
                                setTimeout(function() {
                                    loadingOverlay.classList.remove('active');
                                }, 300);
                            }
                        }, 200);
                    }
                }
            }
        });
    })();
    </script>
    
    <?php
    return ob_get_clean();
}

// شورت‌کد برای نمایش تصاویر محصول
add_shortcode('product_images', function($atts) {
    global $product, $post;
    
    $atts = shortcode_atts(array(
        'id' => null
    ), $atts);
    
    $product_id = $atts['id'];
    
    if (!$product_id) {
        if (is_product() && $product) {
            $product_id = $product->get_id();
        }
        elseif (isset($GLOBALS['product']) && is_object($GLOBALS['product'])) {
            $product_id = $GLOBALS['product']->get_id();
        }
        elseif ($post && $post->post_type === 'product') {
            $product_id = $post->ID;
        }
        elseif (get_query_var('product')) {
            $product_slug = get_query_var('product');
            $product_post = get_page_by_path($product_slug, OBJECT, 'product');
            if ($product_post) {
                $product_id = $product_post->ID;
            }
        }
    }
    
    return custom_product_images($product_id);
});
				
			

و این شرتکد را در جای دلخواه برای گالری تصویر محصول استفاده کنید :

				
					[product_images]

				
			

آموزش و راهنما کد :

آموزش کامل نصب و استفاده از ویجت محصول WooCommerce با انیمیشن قیمت

📌 معرفی

ویجت محصول WooCommerce یک افزونه قدرتمند و کاملاً فارسی است که تجربه خرید کاربران را به سطح حرفه‌ای‌تری می‌برد. این ویجت با انیمیشن‌های جذاب، طراحی مدرن و قابلیت‌های پیشرفته، نرخ تبدیل فروشگاه شما را افزایش می‌دهد.

✨ ویژگی‌های کلیدی

🎬 انیمیشن‌های حرفه‌ای

  • شمارشگر قیمت: قیمت به صورت پویا و با افکت شمارشگر نمایش داده می‌شود
  • انیمیشن تخفیف: نمایش جذاب قیمت تخفیف‌دار با افکت‌های بصری
  • تایمینگ هوشمند: هر المان با تاخیر مناسب برای جلب توجه کاربر ظاهر می‌شود

🛒 قابلیت‌های کاربردی

  • ✅ پشتیبانی کامل از محصولات ساده و متغیر (Variable Products)
  • ✅ مدیریت موجودی به صورت Real-time
  • ✅ افزودن به سبد با AJAX (بدون رفرش صفحه)
  • ✅ کنترل تعداد محصول با دکمه‌های + و –
  • ✅ نمایش پیام‌های هوشمند موجودی
  • ✅ طراحی کاملاً ریسپانسیو (موبایل فرندلی)
  • ✅ پشتیبانی از اعداد فارسی

🎨 طراحی مدرن

  • رنگ‌بندی حرفه‌ای و قابل تنظیم
  • انیمیشن‌های روان و چشم‌نواز
  • رابط کاربری ساده و کاربرپسند
  • سازگار با تمام قالب‌های وردپرس

📥 نصب و راه‌اندازی

مرحله 1️⃣: دریافت کد

ابتدا کد PHP را که در ادامه آورده شده، کپی کنید.

مرحله 2️⃣: افزودن به قالب

روش اول – افزودن به functions.php:

  1. به پنل مدیریت وردپرس بروید
  2. از منوی سمت چپ وارد ظاهر > ویرایشگر فایل‌های قالب شوید
  3. فایل functions.php را باز کنید
  4. کد را در انتهای فایل کپی کنید
  5. روی دکمه به‌روزرسانی فایل کلیک کنید

⚠️ هشدار مهم: قبل از هر تغییری، حتماً از فایل functions.php بکاپ بگیرید!

روش دوم – ایجاد افزونه سفارشی (پیشنهادی):

  1. یک پوشه با نام custom-product-widget در مسیر /wp-content/plugins/ ایجاد کنید
  2. داخل پوشه یک فایل با نام custom-product-widget.php بسازید
  3. کد زیر را در ابتدای فایل قرار دهید:
<?php
/**
 * Plugin Name: ویجت محصول حرفه‌ای
 * Description: ویجت محصول WooCommerce با انیمیشن قیمت
 * Version: 2.4
 * Author: نام شما
 */
  1. سپس کد اصلی ویجت را اضافه کنید
  2. به افزونه‌ها بروید و افزونه را فعال کنید

🚀 نحوه استفاده

1️⃣ استفاده با شورت‌کد

شورت‌کدها ساده‌ترین روش استفاده از ویجت هستند.

نمایش ویجت برای محصول فعلی:

[product_widget]

این شورت‌کد به صورت خودکار ID محصول فعلی را تشخیص می‌دهد.

نمایش ویجت برای محصول خاص:

[product_widget id="123"]

عدد 123 را با شناسه محصول مورد نظر خود جایگزین کنید.

کجا می‌توان شورت‌کد را استفاده کرد؟

الف) در محتوای صفحات و نوشته‌ها:

  1. وارد ویرایشگر صفحه/نوشته شوید
  2. شورت‌کد را در جایی که می‌خواهید ویجت نمایش داده شود، بچسبانید
  3. صفحه را ذخیره کنید

ب) در ویجت‌های سایدبار:

  1. به ظاهر > ابزارک‌ها بروید
  2. یک ابزارک متن یا HTML سفارشی اضافه کنید
  3. شورت‌کد را داخل آن قرار دهید

ج) در صفحه محصول:

  1. به WooCommerce > تنظیمات > محصولات بروید
  2. یا مستقیماً در قالب محصول خود شورت‌کد را اضافه کنید

2️⃣ استفاده مستقیم در فایل‌های PHP

اگر می‌خواهید ویجت را در فایل‌های قالب استفاده کنید:

<?php
// نمایش برای محصول فعلی
echo custom_product_widget();

// نمایش برای محصول خاص
echo custom_product_widget(123); // 123 = شناسه محصول
?>

مثال‌های کاربردی:

الف) افزودن به single-product.php:

<?php
// بعد از عنوان محصول
the_title('<h1>', '</h1>');

// نمایش ویجت
echo custom_product_widget();
?>

ب) نمایش در حلقه محصولات:

<?php
if (have_posts()) :
    while (have_posts()) : the_post();
        global $product;
        echo custom_product_widget($product->get_id());
    endwhile;
endif;
?>

3️⃣ استفاده با صفحه‌سازها (Page Builders)

Elementor:

  1. یک ویجت Shortcode اضافه کنید
  2. شورت‌کد را وارد کنید
  3. استایل را تنظیم کنید

WPBakery:

  1. یک Raw HTML یا Text Block اضافه کنید
  2. شورت‌کد را قرار دهید

Gutenberg:

  1. بلاک Shortcode را اضافه کنید
  2. شورت‌کد را وارد کنید

🎨 شخصی‌سازی ظاهر

تغییر رنگ‌ها

رنگ‌های اصلی در بخش CSS کد قرار دارند. برای تغییر آن‌ها:

/* رنگ دکمه افزودن به سبد */
.widget-add-to-cart-btn {
    background: #F85811; /* رنگ اصلی */
}

.widget-add-to-cart-btn:hover {
    background: #d94a0d; /* رنگ هاور */
}

/* رنگ گزینه انتخاب شده */
.widget-attribute-option.selected {
    background: #1f2937; /* رنگ پس‌زمینه */
    border-color: #1f2937; /* رنگ حاشیه */
}

/* رنگ قیمت تخفیف */
.widget-sale-price {
    color: #059669; /* رنگ قیمت تخفیف‌دار */
}

/* رنگ بج تخفیف */
.widget-discount-badge {
    background: linear-gradient(135deg, #ef4444, #dc2626);
}

تنظیم سرعت انیمیشن

برای تغییر سرعت انیمیشن شمارشگر قیمت، خط زیر را در بخش JavaScript پیدا کنید:

function animatePrice(element, targetPrice, callback) {
    var duration = 800; // سرعت انیمیشن (میلی‌ثانیه)
    var steps = 30;     // تعداد مراحل انیمیشن
    
    // هر چه duration کمتر باشد، انیمیشن سریع‌تر است
    // هر چه steps بیشتر باشد، انیمیشن نرم‌تر است
}

پیشنهادات:

  • سریع: duration = 500, steps = 20
  • معمولی: duration = 800, steps = 30 (پیش‌فرض)
  • آرام: duration = 1200, steps = 40

تغییر فونت

.custom-product-widget {
    font-family: 'shabnam'; /* فونت پیش‌فرض */
}

/* برای استفاده از فونت دلخواه: */
.custom-product-widget {
    font-family: 'Vazir', 'Tahoma', sans-serif;
}

🔧 تنظیمات پیشرفته

غیرفعال کردن انیمیشن

اگر نمی‌خواهید انیمیشن شمارشگر داشته باشید:

// این بخش را پیدا کنید:
animatePrice(priceElement.querySelector('.widget-price'), Math.round(displayPrice), ...

// و با این جایگزین کنید:
var formattedPrice = convertToPersianNumber(Math.round(displayPrice).toLocaleString('en-US'));
priceElement.querySelector('.widget-price').innerHTML = formattedPrice + currencyText;

تغییر پیام موجودی

پیام “تنها X عدد در انبار باقی مانده” را می‌توانید تغییر دهید:

// این خط را پیدا کنید:
newStockInfo.textContent = 'تنها ' + convertToPersianNumber(maxQty) + ' عدد در انبار باقی مانده';

// و متن دلخواه خود را بنویسید:
newStockInfo.textContent = 'فقط ' + convertToPersianNumber(maxQty) + ' عدد موجود است!';

تغییر حد آستانه موجودی کم

به صورت پیش‌فرض، اگر موجودی کمتر از 5 عدد باشد، پیام نمایش داده می‌شود:

// در بخش PHP این خط را پیدا کنید:
<?php if ($is_in_stock && $manage_stock && $stock_quantity > 0 && $stock_quantity <= 5): ?>

// عدد 5 را تغییر دهید، مثلاً برای 10 عدد:
<?php if ($is_in_stock && $manage_stock && $stock_quantity > 0 && $stock_quantity <= 10): ?>

تغییر شماره تماس

پیام “برای اطلاع از قیمت تماس بگیرید” را می‌توانید سفارشی کنید:

// این خط را پیدا کنید:
return '<p style="...">برای اطلاع از قیمت این محصول تماس بگیرید، شماره تماس: 09128008175</p>';

// و با شماره و متن دلخواه جایگزین کنید:
return '<p style="...">برای استعلام قیمت با ما تماس بگیرید: 021-12345678</p>';

📱 نکات موبایل فرندلی

ویجت به صورت خودکار برای موبایل بهینه شده است، اما می‌توانید تنظیمات را شخصی‌سازی کنید:

@media (max-width: 640px) {
    /* اندازه فونت دکمه */
    .widget-add-to-cart-btn {
        font-size: 14px; /* می‌توانید تغییر دهید */
    }
    
    /* اندازه گزینه‌ها */
    .widget-attribute-option {
        padding: 6px 12px; /* فاصله داخلی */
        font-size: 13px;   /* اندازه فونت */
    }
}

🐛 رفع مشکلات رایج

مشکل 1: ویجت نمایش داده نمی‌شود

راه‌حل:

  • بررسی کنید WooCommerce نصب و فعال باشد
  • کد را در جای درست کپی کرده باشید
  • Cache سایت را پاک کنید
  • مرورگر را رفرش کنید (Ctrl+F5)

مشکل 2: قیمت به‌روز نمی‌شود

راه‌حل:

  • کنسول مرورگر را چک کنید (F12)
  • مطمئن شوید jQuery بارگذاری شده است
  • بررسی کنید محصول از نوع Variable باشد
  • ویژگی‌های محصول را صحیح تنظیم کرده باشید

مشکل 3: انیمیشن کار نمی‌کند

راه‌حل:

  • بررسی کنید JavaScript در مرورگر فعال باشد
  • از آخرین نسخه مرورگر استفاده کنید
  • تداخل با افزونه‌های دیگر را بررسی کنید

مشکل 4: دکمه افزودن به سبد کار نمی‌کند

راه‌حل:

// مطمئن شوید این خطوط در functions.php هستند:
add_action('wp_ajax_custom_add_to_cart', 'handle_custom_add_to_cart');
add_action('wp_ajax_nopriv_custom_add_to_cart', 'handle_custom_add_to_cart');

مشکل 5: اعداد فارسی نمایش داده نمی‌شود

راه‌حل:

  • بررسی کنید تابع convert_to_persian_numbers در کد موجود باشد
  • فونت مناسب برای اعداد فارسی استفاده کنید

💡 نکات بهینه‌سازی

1. کش (Cache)

ویجت کاملاً با افزونه‌های کش سازگار است. در صورت بروز مشکل:

// این کد را اضافه کنید تا ویجت از کش معاف شود:
add_filter('rocket_cache_reject_uri', function($urls) {
    $urls[] = '/shop/(.*)';
    return $urls;
});

2. سرعت بارگذاری

برای بهبود سرعت:

  • از CDN برای فونت‌ها استفاده کنید
  • تصاویر محصولات را بهینه کنید
  • از کش مرورگر استفاده کنید

3. SEO

برای بهبود سئو:

  • از متا تگ‌های مناسب استفاده کنید
  • قیمت‌ها را با Schema Markup مشخص کنید
  • از متن جایگزین برای تصاویر استفاده کنید

🎯 موارد استفاده پیشنهادی

1. فروشگاه پوشاک

  • نمایش سایزها و رنگ‌ها
  • مدیریت موجودی برای هر سایز

2. فروشگاه لوازم الکترونیکی

  • نمایش مشخصات فنی
  • قیمت‌گذاری پویا

3. فروشگاه مواد غذایی

  • وزن‌های مختلف
  • قیمت به ازای هر کیلو

4. فروشگاه کتاب

  • نسخه‌های مختلف (چاپی، PDF)
  • تخفیف‌های ویژه

🔐 امنیت

ویجت دارای تمهیدات امنیتی زیر است:

Nonce Verification: جلوگیری از حملات CSRF ✅ Data Sanitization: پاکسازی ورودی‌ها ✅ Escape Output: امن‌سازی خروجی‌ها ✅ Permission Check: بررسی دسترسی‌ها


📊 گزارش و آمار

برای مشاهده آمار فروش ویجت:

  1. به WooCommerce > گزارش‌ها بروید
  2. تب سفارشات را انتخاب کنید
  3. فیلتر تاریخ را تنظیم کنید

🆘 پشتیبانی

در صورت بروز مشکل:

  1. مستندات را مطالعه کنید
  2. کنسول مرورگر را بررسی کنید (F12)
  3. نسخه WooCommerce را به‌روز کنید
  4. افزونه‌های تداخل‌کننده را غیرفعال کنید

📝 لایسنس

این کد تحت لایسنس GPL v2 یا بالاتر منتشر شده است و می‌توانید آزادانه استفاده، تغییر و توزیع کنید.


🎉 نتیجه‌گیری

ویجت محصول WooCommerce با انیمیشن قیمت، ابزاری قدرتمند برای افزایش نرخ تبدیل فروشگاه آنلاین شماست. با استفاده از این آموزش می‌توانید به راحتی آن را نصب، پیکربندی و سفارشی‌سازی کنید.

نکات پایانی:

  • همیشه قبل از تغییرات، بکاپ بگیرید
  • در محیط تست ابتدا امتحان کنید
  • از نسخه‌های به‌روز افزونه‌ها استفاده کنید
  • تجربه کاربری را اولویت قرار دهید

📞 تماس با ما

برای سفارش طراحی و توسعه اختصاصی، با ما در تماس باشید:

  • 📧 ایمیل: info@example.com
  • 📱 تلگرام: @YourTelegram
  • 🌐 وبسایت: www.example.com

موفق و پرفروش باشید! 🚀

نظرات شما