motayeb/woocommerce/content-product.php
Kazem Alghasi c16648678d - install local Tailwind
- fix more problems
2026-09-23 00:32:16 +03:30

215 lines
11 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* کارت محصول - سفارشی مطابق با طراحی مطیب (با AJAX و علاقه‌مندی)
*
* @package Motayeb
* @version 1.0.1
*
* تغییرات نسخه ۱.۰.۱:
* - guard کامل WooCommerce (بدون fatal error اگه غیرفعال باشه)
* - data-product-id و data-wishlist-btn برای هماهنگی با main.js
* - مدیریت محصولات متغیر (هدایت به صفحه محصول به‌جای quick-add)
* - مدیریت محصولات ناموجود (برچسب "ناموجود" + دکمه غیرفعال)
* - number_format_i18n برای اعداد فارسی
* - loading="lazy" + width/height + decoding="async" روی تصاویر
* - aria-label روی دکمه‌های آیکونی
* - Schema.org Product markup
* - نمایش دسته‌بندی محصول
* - برچسب‌های بهتر: تخفیف، ویژه، ناموجود
*/
defined( 'ABSPATH' ) || exit;
global $product;
// guard: اگه ووکامرس غیرفعال باشه یا محصول معتبر نباشه
if ( ! class_exists( 'WooCommerce' ) || ! is_a( $product, 'WC_Product' ) ) {
return;
}
// دریافت داده‌های ضروری
$product_id = $product->get_id();
$product_name = $product->get_name();
$product_link = $product->get_permalink();
$image_id = $product->get_image_id();
// تصویر محصول با fallback
$img_src = '';
$img_width = 400;
$img_height = 400;
if ( $image_id ) {
$image_data = wp_get_attachment_image_src( $image_id, 'medium' );
if ( $image_data ) {
$img_src = $image_data[0];
$img_width = $image_data[1];
$img_height = $image_data[2];
}
}
if ( ! $img_src ) {
$img_src = 'https://picsum.photos/seed/' . $product_id . '/400/400.jpg';
}
// امتیاز و تعداد نظرات
$rating = $product->get_average_rating();
$review_count = $product->get_rating_count();
// وضعیت‌های محصول
$is_on_sale = $product->is_on_sale();
$is_featured = $product->is_featured();
$is_in_stock = $product->is_in_stock();
$is_variable = $product->is_type( 'variable' );
// محاسبه درصد تخفیف
$discount_percent = 0;
if ( $is_on_sale ) {
$regular_price = (float) $product->get_regular_price();
$sale_price = (float) $product->get_sale_price();
if ( $regular_price > 0 && $sale_price < $regular_price ) {
$discount_percent = round( ( ( $regular_price - $sale_price ) / $regular_price ) * 100 );
}
}
// دسته‌بندی محصول (اولین دسته)
$product_cats = wp_get_post_terms( $product_id, 'product_cat', array( 'fields' => 'names' ) );
$first_cat = ! empty( $product_cats ) && ! is_wp_error( $product_cats ) ? $product_cats[0] : '';
// قیمت HTML (بدون wp_kses_post — خود ووکامرس امنه)
$price_html = $product->get_price_html();
// تعیین نوع دکمه افزودن به سبد
$button_action = 'quick'; // پیش‌فرض: quick-add
$button_label = 'افزودن';
$button_icon = 'lucide:shopping-bag';
$button_disabled = false;
if ( ! $is_in_stock ) {
$button_action = 'none';
$button_label = 'ناموجود';
$button_icon = 'lucide:x-circle';
$button_disabled = true;
} elseif ( $is_variable ) {
$button_action = 'view'; // محصول متغیر: هدایت به صفحه محصول
$button_label = 'مشاهده';
$button_icon = 'lucide:eye';
}
?>
<div <?php wc_product_class( 'product-card group bg-white dark:bg-dark-card rounded-2xl overflow-hidden border border-cream-200/50 dark:border-dark-border/50 hover:shadow-xl transition-all relative w-full', $product ); ?>
itemscope itemtype="https://schema.org/Product">
<!-- متادیتای Schema.org (مخفی) -->
<meta itemprop="productID" content="<?php echo esc_attr( $product_id ); ?>">
<meta itemprop="name" content="<?php echo esc_attr( $product_name ); ?>">
<meta itemprop="url" content="<?php echo esc_attr( $product_link ); ?>">
<div itemprop="offers" itemscope itemtype="https://schema.org/Offer" class="hidden">
<meta itemprop="price" content="<?php echo esc_attr( $product->get_price() ); ?>">
<meta itemprop="priceCurrency" content="IRR">
<link itemprop="availability" href="<?php echo $is_in_stock ? 'https://schema.org/InStock' : 'https://schema.org/OutOfStock'; ?>">
</div>
<!-- عکس و لینک محصول -->
<a href="<?php echo esc_url( $product_link ); ?>" class="block relative overflow-hidden bg-cream-100 dark:bg-dark-bg" aria-label="<?php echo esc_attr( sprintf( __( 'مشاهده %s', 'motayeb' ), $product_name ) ); ?>">
<img src="<?php echo esc_url( $img_src ); ?>"
alt="<?php echo esc_attr( $product_name ); ?>"
width="<?php echo esc_attr( $img_width ); ?>"
height="<?php echo esc_attr( $img_height ); ?>"
loading="lazy"
decoding="async"
class="product-img w-full h-48 md:h-56 object-cover">
<!-- برچسب‌های بالای عکس -->
<div class="absolute top-3 right-3 flex flex-col gap-1.5">
<?php if ( ! $is_in_stock ) : ?>
<span class="px-2.5 py-1 bg-cream-400 dark:bg-dark-muted text-white text-[10px] rounded-full font-medium">ناموجود</span>
<?php elseif ( $is_featured ) : ?>
<span class="px-2.5 py-1 bg-forest-500 text-white text-[10px] rounded-full font-medium">ویژه</span>
<?php endif; ?>
<?php if ( $discount_percent > 0 ) : ?>
<span class="px-2.5 py-1 bg-red-500 text-white text-[10px] rounded-full font-medium">
<?php echo esc_html( number_format_i18n( $discount_percent ) ); ?>٪ تخفیف
</span>
<?php endif; ?>
</div>
<?php if ( ! $is_in_stock ) : ?>
<!-- overlay ناموجود -->
<div class="absolute inset-0 bg-white/40 dark:bg-dark-bg/40 flex items-center justify-center">
<span class="px-4 py-2 bg-cream-400 dark:bg-dark-muted text-white text-xs font-bold rounded-xl">ناموجود</span>
</div>
<?php endif; ?>
</a>
<!-- دکمه‌های عملیات (هاور در دسکتاپ، همیشه در موبایل) -->
<?php if ( $is_in_stock ) : ?>
<div class="quick-actions absolute bottom-3 left-3 right-3 flex gap-2 z-10">
<?php if ( $button_action === 'view' ) : ?>
<!-- محصول متغیر: هدایت به صفحه محصول -->
<a href="<?php echo esc_url( $product_link ); ?>"
class="flex-1 py-2.5 bg-white/90 dark:bg-dark-card/90 backdrop-blur rounded-xl text-xs font-bold hover:bg-forest-500 hover:text-white transition flex items-center justify-center gap-1">
<iconify-icon icon="<?php echo esc_attr( $button_icon ); ?>" width="14"></iconify-icon>
<span><?php echo esc_html( $button_label ); ?></span>
</a>
<?php else : ?>
<!-- محصول ساده: افزودن با AJAX -->
<button onclick="quickAddToCart(<?php echo esc_js( $product_id ); ?>)"
class="flex-1 py-2.5 bg-white/90 dark:bg-dark-card/90 backdrop-blur rounded-xl text-xs font-bold hover:bg-forest-500 hover:text-white transition flex items-center justify-center gap-1"
aria-label="<?php echo esc_attr( sprintf( __( 'افزودن %s به سبد خرید', 'motayeb' ), $product_name ) ); ?>">
<iconify-icon icon="<?php echo esc_attr( $button_icon ); ?>" width="14"></iconify-icon>
<span><?php echo esc_html( $button_label ); ?></span>
</button>
<?php endif; ?>
<!-- دکمه علاقه‌مندی‌ها -->
<button onclick="toggleWishlist(this, <?php echo esc_js( $product_id ); ?>)"
data-wishlist-btn
data-product-id="<?php echo esc_attr( $product_id ); ?>"
class="w-10 h-10 bg-white/90 dark:bg-dark-card/90 backdrop-blur rounded-xl flex items-center justify-center hover:bg-red-50 hover:text-red-500 transition"
aria-label="<?php echo esc_attr( sprintf( __( 'افزودن %s به علاقه‌مندی‌ها', 'motayeb' ), $product_name ) ); ?>">
<iconify-icon icon="lucide:heart" width="16"></iconify-icon>
</button>
</div>
<?php endif; ?>
<!-- اطلاعات محصول -->
<div class="p-4">
<!-- دسته‌بندی -->
<?php if ( $first_cat ) : ?>
<div class="text-[10px] text-cream-500 dark:text-dark-muted mb-1.5 font-medium uppercase tracking-wide"><?php echo esc_html( $first_cat ); ?></div>
<?php endif; ?>
<!-- عنوان -->
<a href="<?php echo esc_url( $product_link ); ?>"
class="block font-bold text-sm line-clamp-2 mb-3 group-hover:text-forest-500 dark:group-hover:text-forest-300 transition leading-relaxed"
itemprop="name">
<?php echo esc_html( $product_name ); ?>
</a>
<!-- ستاره‌ها -->
<?php if ( $rating > 0 ) : ?>
<div class="flex items-center gap-1 mb-2" itemprop="aggregateRating" itemscope itemtype="https://schema.org/AggregateRating">
<span class="text-honey-400 text-xs" aria-hidden="true">★</span>
<span class="text-xs font-medium"><?php echo esc_html( number_format_i18n( $rating, 1 ) ); ?></span>
<span class="text-xs text-cream-400 dark:text-dark-muted">(<?php echo esc_html( number_format_i18n( $review_count ) ); ?>)</span>
<meta itemprop="ratingValue" content="<?php echo esc_attr( $rating ); ?>">
<meta itemprop="reviewCount" content="<?php echo esc_attr( $review_count ); ?>">
</div>
<?php else : ?>
<div class="flex items-center gap-1 mb-2">
<span class="text-cream-300 dark:text-dark-muted text-xs" aria-hidden="true">★★★★★</span>
<span class="text-xs text-cream-400 dark:text-dark-muted">بدون امتیاز</span>
</div>
<?php endif; ?>
<!-- قیمت -->
<div class="flex items-end gap-2" itemprop="price">
<?php if ( $is_in_stock ) : ?>
<span class="font-extrabold text-forest-500 dark:text-forest-300 text-sm md:text-base">
<?php echo $price_html; // ووکامرس خودش escape می‌کنه ?>
</span>
<?php else : ?>
<span class="font-bold text-cream-400 dark:text-dark-muted text-sm italic">ناموجود</span>
<?php endif; ?>
</div>
</div>
</div>