433 lines
15 KiB
PHP
433 lines
15 KiB
PHP
<?php
|
||
/**
|
||
* ادغام ووکامرس با Hesabix2 — فقط وقتی افزونه فعال است.
|
||
*
|
||
* @package Hesabix2
|
||
*/
|
||
|
||
if ( ! defined( 'ABSPATH' ) ) {
|
||
exit;
|
||
}
|
||
|
||
/**
|
||
* آیا ووکامرس در دسترس است؟
|
||
*/
|
||
function hesabix2_is_woocommerce_active() {
|
||
return class_exists( 'WooCommerce', false );
|
||
}
|
||
|
||
/**
|
||
* صفحات برگهٔ وردپرس که بدنهٔ مختصر دارند (سبد، پرداخت، حساب).
|
||
*/
|
||
function hesabix2_wc_is_secondary_page_layout() {
|
||
if ( ! hesabix2_is_woocommerce_active() ) {
|
||
return false;
|
||
}
|
||
return function_exists( 'is_cart' ) && ( is_cart() || is_checkout() || is_account_page() );
|
||
}
|
||
|
||
/**
|
||
* نمایش ستون کناری فقط در فروشگاه و آرشیوهای محصول؛ نه PDP، نه صفحات فرعی.
|
||
*/
|
||
function hesabix2_wc_show_shop_sidebar_column() {
|
||
if ( ! hesabix2_is_woocommerce_active() || ! is_active_sidebar( 'hesabix2-shop-sidebar' ) ) {
|
||
return false;
|
||
}
|
||
if ( function_exists( 'is_cart' ) && ( is_cart() || is_checkout() || is_account_page() ) ) {
|
||
return false;
|
||
}
|
||
if ( function_exists( 'is_product' ) && is_product() ) {
|
||
return false;
|
||
}
|
||
if ( function_exists( 'is_product_taxonomy' ) && is_product_taxonomy() ) {
|
||
return true;
|
||
}
|
||
if ( function_exists( 'is_shop' ) && is_shop() ) {
|
||
return true;
|
||
}
|
||
if ( function_exists( 'is_post_type_archive' ) && is_post_type_archive( 'product' ) ) {
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* پشتیبانی تم و گالری محصول.
|
||
*/
|
||
function hesabix2_wc_setup_theme() {
|
||
if ( ! hesabix2_is_woocommerce_active() ) {
|
||
return;
|
||
}
|
||
add_theme_support( 'woocommerce' );
|
||
add_theme_support( 'wc-product-gallery-zoom' );
|
||
add_theme_support( 'wc-product-gallery-lightbox' );
|
||
add_theme_support( 'wc-product-gallery-slider' );
|
||
}
|
||
add_action( 'after_setup_theme', 'hesabix2_wc_setup_theme', 11 );
|
||
|
||
/**
|
||
* استایلهای پیشفرض ووکامرس غیرفعال — قالب استایل اختصاصی دارد.
|
||
*/
|
||
function hesabix2_wc_dequeue_plugin_styles( $styles ) {
|
||
if ( ! hesabix2_is_woocommerce_active() ) {
|
||
return $styles;
|
||
}
|
||
return array();
|
||
}
|
||
add_filter( 'woocommerce_enqueue_styles', 'hesabix2_wc_dequeue_plugin_styles' );
|
||
|
||
/**
|
||
* حذف لفافهای پیشفرض و نانریزهٔ جایگزین با قالب hesabix2 (در woocommerce.php فراخوانی دستی).
|
||
*/
|
||
function hesabix2_wc_remove_default_wrappers() {
|
||
if ( ! hesabix2_is_woocommerce_active() ) {
|
||
return;
|
||
}
|
||
remove_action( 'woocommerce_before_main_content', 'woocommerce_output_content_wrapper', 10 );
|
||
remove_action( 'woocommerce_after_main_content', 'woocommerce_output_content_wrapper_end', 10 );
|
||
remove_action( 'woocommerce_before_main_content', 'woocommerce_breadcrumb', 20 );
|
||
}
|
||
add_action( 'wp', 'hesabix2_wc_remove_default_wrappers', 5 );
|
||
|
||
/**
|
||
* بارگذاری استایل اختصاصی فروشگاه.
|
||
*/
|
||
function hesabix2_wc_enqueue_assets() {
|
||
if ( ! hesabix2_is_woocommerce_active() ) {
|
||
return;
|
||
}
|
||
|
||
$dir = get_template_directory();
|
||
$url = get_template_directory_uri();
|
||
|
||
$file_css = $dir . '/assets/css/woocommerce.css';
|
||
wp_enqueue_style(
|
||
'hesabix2-woocommerce',
|
||
$url . '/assets/css/woocommerce.css',
|
||
array( 'hesabix2-style' ),
|
||
file_exists( $file_css ) ? (string) filemtime( $file_css ) : '1.0.1'
|
||
);
|
||
|
||
$file_js = $dir . '/assets/js/woocommerce-front.js';
|
||
if ( file_exists( $file_js ) ) {
|
||
$deps = array( 'jquery' );
|
||
if ( wp_script_is( 'wc-cart-fragments', 'registered' ) ) {
|
||
$deps[] = 'wc-cart-fragments';
|
||
}
|
||
wp_enqueue_script(
|
||
'hesabix2-wc-front',
|
||
$url . '/assets/js/woocommerce-front.js',
|
||
$deps,
|
||
(string) filemtime( $file_js ),
|
||
true
|
||
);
|
||
}
|
||
}
|
||
add_action( 'wp_enqueue_scripts', 'hesabix2_wc_enqueue_assets', 110 );
|
||
|
||
/**
|
||
* کلاس بدنهٔ صفحات ووکامرس.
|
||
*
|
||
* @param string[] $classes کلاسها.
|
||
* @return string[]
|
||
*/
|
||
function hesabix2_wc_body_classes( $classes ) {
|
||
if ( ! hesabix2_is_woocommerce_active() ) {
|
||
return $classes;
|
||
}
|
||
|
||
if ( hesabix2_wc_is_secondary_page_layout() ) {
|
||
$classes[] = 'hesabix-wc-secondary-page';
|
||
}
|
||
|
||
if ( function_exists( 'is_woocommerce' ) && is_woocommerce() ) {
|
||
$classes[] = 'woocommerce hesabix-woocommerce';
|
||
} elseif ( is_singular( 'product' ) || ( function_exists( 'is_shop' ) && is_shop() ) ) {
|
||
$classes[] = 'woocommerce hesabix-woocommerce';
|
||
}
|
||
|
||
if ( hesabix2_wc_show_shop_sidebar_column() ) {
|
||
$classes[] = 'hesabix-wc-with-sidebar';
|
||
}
|
||
|
||
if ( function_exists( 'is_cart' ) && is_cart() ) {
|
||
$classes[] = 'hesabix-wc-cart';
|
||
}
|
||
if ( function_exists( 'is_checkout' ) && is_checkout() ) {
|
||
$classes[] = 'hesabix-wc-checkout';
|
||
}
|
||
if ( function_exists( 'is_account_page' ) && is_account_page() ) {
|
||
$classes[] = 'hesabix-wc-account';
|
||
}
|
||
if ( function_exists( 'is_product' ) && is_product() ) {
|
||
$classes[] = 'hesabix-wc-single-product';
|
||
}
|
||
|
||
if ( function_exists( 'is_shop' ) && is_shop() ) {
|
||
$classes[] = 'hesabix-wc-shop-archive';
|
||
}
|
||
if ( function_exists( 'is_product_taxonomy' ) && is_product_taxonomy() ) {
|
||
$classes[] = 'hesabix-wc-shop-archive';
|
||
}
|
||
if ( function_exists( 'is_post_type_archive' ) && is_post_type_archive( 'product' ) ) {
|
||
$classes[] = 'hesabix-wc-shop-archive';
|
||
}
|
||
|
||
return $classes;
|
||
}
|
||
add_filter( 'body_class', 'hesabix2_wc_body_classes' );
|
||
|
||
/**
|
||
* تعداد ستونهای گرید آرشیو (ریسپانسیو از CSS کنترل میشود؛ این عدد پایه است).
|
||
*
|
||
* @return int ستونها.
|
||
*/
|
||
function hesabix2_wc_loop_columns() {
|
||
return (int) apply_filters( 'hesabix2_wc_shop_columns', 3 );
|
||
}
|
||
|
||
/**
|
||
* ستون آرشیو.
|
||
*
|
||
* @return int
|
||
*/
|
||
function hesabix2_wc_product_columns() {
|
||
return hesabix2_wc_loop_columns();
|
||
}
|
||
add_filter( 'loop_shop_columns', 'hesabix2_wc_product_columns', 20 );
|
||
|
||
/**
|
||
* ستون اصلی محتوای WooCommerce در woocommerce.php.
|
||
*/
|
||
function hesabix2_wc_render_main_column() {
|
||
?>
|
||
<main id="woocommerce-main" class="hesabix-wc__main" role="main">
|
||
<div class="page-card hesabix-wc__card">
|
||
<?php
|
||
/**
|
||
* woocommerce_before_main_content — شامل دادهٔ ساختاری بدون لفاف پیشفرض تم.
|
||
*/
|
||
do_action( 'woocommerce_before_main_content' );
|
||
|
||
woocommerce_content();
|
||
|
||
do_action( 'woocommerce_after_main_content' );
|
||
?>
|
||
</div>
|
||
</main>
|
||
<?php
|
||
}
|
||
|
||
/**
|
||
* رندر ستون کناری ویجت فروشگاه.
|
||
*/
|
||
function hesabix2_wc_render_sidebar() {
|
||
if ( ! hesabix2_wc_show_shop_sidebar_column() ) {
|
||
return;
|
||
}
|
||
|
||
echo '<aside class="hesabix-wc__sidebar sticky top-28 self-start" aria-label="' . esc_attr__( 'فیلتر و ابزارهای فروشگاه', 'hesabix2' ) . '" role="complementary">';
|
||
echo '<div class="hesabix-wc__sidebar-inner">';
|
||
get_sidebar( 'shop' );
|
||
echo '</div></aside>';
|
||
}
|
||
|
||
/**
|
||
* قطعه HTML نشانٔ تعداد سبد برای AJAX fragments ووکامرس.
|
||
*
|
||
* @return string
|
||
*/
|
||
function hesabix2_wc_get_cart_count_badge_html() {
|
||
if ( ! hesabix2_is_woocommerce_active() || null === WC()->cart ) {
|
||
return '';
|
||
}
|
||
$count = WC()->cart->get_cart_contents_count();
|
||
if ( $count < 1 ) {
|
||
return '';
|
||
}
|
||
|
||
return sprintf(
|
||
'<span class="hesabix-wc-header-cart__badge hesabix-wc-header-cart__badge--count" aria-hidden="true">%s</span>',
|
||
esc_html( number_format_i18n( min( $count, 99 ) ) . ( $count > 99 ? '+' : '' ) )
|
||
);
|
||
}
|
||
|
||
/**
|
||
* بدنهٔ مینیسبد (محتوایی که با AJAX بازتولید میشود — بدون لفاف خارجی قطعهٔ replace).
|
||
*
|
||
* @return string
|
||
*/
|
||
function hesabix2_wc_get_mini_cart_inner_markup() {
|
||
ob_start();
|
||
|
||
echo '<div class="hesabix-wc-mini-cart__frag hesabix-wc-mini-cart__frag--inner">';
|
||
woocommerce_mini_cart();
|
||
echo '</div>';
|
||
|
||
return ob_get_clean();
|
||
}
|
||
|
||
/**
|
||
* ناحیهٔ سبد در هدر: دکمه کشوی مینیسبد + لینک سریع (فقط lg+).
|
||
*/
|
||
function hesabix2_wc_render_header_cart() {
|
||
if ( ! hesabix2_is_woocommerce_active() ) {
|
||
return;
|
||
}
|
||
|
||
$cart_url = wc_get_cart_url();
|
||
$checkout_url = wc_get_checkout_url();
|
||
$qty = ( WC()->cart && ! WC()->cart->is_empty() ) ? WC()->cart->get_cart_contents_count() : 0;
|
||
|
||
?>
|
||
|
||
<div class="hesabix-wc-mini-cart-wrap hidden lg:flex items-center shrink-0 relative">
|
||
<button
|
||
type="button"
|
||
class="hesabix-wc-mini-cart__trigger flex items-center justify-center gap-2 relative rounded-xl border border-slate-200/90 bg-white hover:bg-light-50 hover:border-brand-200 text-slate-700 hover:text-brand-600 transition-all duration-200 px-3 py-2 min-h-[2.625rem] cursor-pointer"
|
||
id="hesabix-wc-mini-cart-trigger"
|
||
aria-expanded="false"
|
||
aria-haspopup="dialog"
|
||
aria-controls="hesabix-wc-mini-cart-panel"
|
||
aria-label="<?php echo esc_attr__( 'سبد خرید — باز کردن پیشنمایش', 'hesabix2' ); ?>"
|
||
>
|
||
<span class="hesabix-wc-header-cart__icon" aria-hidden="true">
|
||
<svg class="w-5 h-5 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.75"><path stroke-linecap="round" stroke-linejoin="round" d="M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z"/><path stroke-linecap="round" stroke-linejoin="round" d="M9 21a1 1 0 100-2 1 1 0 000 2zm6 0a1 1 0 100-2 1 1 0 000 2z"/></svg>
|
||
</span>
|
||
<span class="hesabix-wc-header-cart__counts text-sm font-semibold tabular-nums hesabix-wc-fragment-desktop"><?php echo hesabix2_wc_get_cart_count_badge_html(); ?></span>
|
||
</button>
|
||
|
||
<div
|
||
class="hesabix-wc-mini-cart-panel rounded-2xl border border-slate-200 bg-white shadow-2xl shadow-slate-900/12 ring-1 ring-black/5 z-[120]"
|
||
id="hesabix-wc-mini-cart-panel"
|
||
role="dialog"
|
||
aria-label="<?php echo esc_attr__( 'پیشنمایش سبد خرید', 'hesabix2' ); ?>"
|
||
aria-modal="false"
|
||
hidden
|
||
>
|
||
<div class="hesabix-wc-mini-cart-panel__head flex items-center justify-between gap-2 px-4 py-3 border-b border-slate-100 bg-gradient-to-l from-brand-500/12 via-transparent to-accent-500/8">
|
||
<span class="text-sm font-bold text-slate-800"><?php esc_html_e( 'سبد شما', 'hesabix2' ); ?></span>
|
||
<?php if ( $qty > 0 ) : ?>
|
||
<span class="hesabix-wc-mini-cart-panel__pill text-xs font-semibold tabular-nums px-2.5 py-1 rounded-full bg-brand-500 text-white"><?php echo esc_html( sprintf( __( '%s قلم', 'hesabix2' ), number_format_i18n( $qty ) ) ); ?></span>
|
||
<?php else : ?>
|
||
<span class="hesabix-wc-mini-cart-panel__pill hesabix-wc-mini-cart-panel__pill--empty inline-block min-h-[1.5rem]" aria-hidden="true"></span>
|
||
<?php endif; ?>
|
||
</div>
|
||
<div class="hesabix-wc-mini-cart-panel__body max-h-[min(70vh,28rem)] overflow-y-auto overscroll-contain px-3 py-2">
|
||
<div class="hesabix-wc-mini-cart__ajax"><?php echo hesabix2_wc_get_mini_cart_inner_markup(); ?></div>
|
||
</div>
|
||
<div class="hesabix-wc-mini-cart-panel__foot flex gap-2 p-3 border-t border-slate-100 bg-slate-50/90">
|
||
<a href="<?php echo esc_url( $cart_url ); ?>" class="flex-1 text-center text-xs sm:text-sm font-semibold px-3 py-2.5 rounded-xl border border-slate-200 bg-white text-slate-700 hover:border-brand-300 hover:text-brand-600 transition no-underline">
|
||
<?php esc_html_e( 'مشاهده سبد', 'hesabix2' ); ?>
|
||
</a>
|
||
<a href="<?php echo esc_url( $checkout_url ); ?>" class="flex-1 text-center text-xs sm:text-sm font-semibold px-3 py-2.5 rounded-xl bg-gradient-to-l from-brand-500 to-brand-600 text-white shadow-md shadow-brand-500/25 hover:shadow-lg transition no-underline">
|
||
<?php esc_html_e( 'پرداخت', 'hesabix2' ); ?>
|
||
</a>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
<?php
|
||
}
|
||
|
||
/**
|
||
* لینک سبد در دراور موبایل.
|
||
*/
|
||
function hesabix2_wc_render_mobile_cart_link() {
|
||
if ( ! hesabix2_is_woocommerce_active() ) {
|
||
return;
|
||
}
|
||
|
||
$url = wc_get_cart_url();
|
||
?>
|
||
|
||
<a href="<?php echo esc_url( $url ); ?>" class="hesabix-mobile-link hesabix-wc-mobile-cart flex items-center gap-3 py-4 px-4 rounded-xl text-slate-700 hover:text-brand-600 hover:bg-light-100 font-medium transition">
|
||
<span class="hesabix-wc-header-cart__icon flex-shrink-0" aria-hidden="true">
|
||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.75"><path stroke-linecap="round" stroke-linejoin="round" d="M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z"/><path stroke-linecap="round" stroke-linejoin="round" d="M9 21a1 1 0 100-2 1 1 0 000 2zm6 0a1 1 0 100-2 1 1 0 000 2z"/></svg>
|
||
</span>
|
||
<span><?php esc_html_e( 'سبد خرید', 'hesabix2' ); ?></span>
|
||
<span class="hesabix-wc-mobile-cart__badge ms-auto text-sm hesabix-wc-fragment-mobile"><?php echo hesabix2_wc_get_cart_count_badge_html(); ?></span>
|
||
</a>
|
||
<?php
|
||
}
|
||
|
||
/**
|
||
* بهروزرسانی قطعات سبد پس از AJAX.
|
||
*
|
||
* @param array<string, string> $fragments قطعات موجود.
|
||
* @return array<string, string>
|
||
*/
|
||
function hesabix2_wc_add_cart_fragments( $fragments ) {
|
||
if ( ! hesabix2_is_woocommerce_active() ) {
|
||
return $fragments;
|
||
}
|
||
|
||
$b = hesabix2_wc_get_cart_count_badge_html();
|
||
|
||
$fragments['.hesabix-wc-fragment-desktop'] = sprintf(
|
||
'<span class="hesabix-wc-header-cart__counts text-sm font-semibold tabular-nums hesabix-wc-fragment-desktop">%s</span>',
|
||
$b
|
||
);
|
||
$fragments['.hesabix-wc-fragment-mobile'] = sprintf(
|
||
'<span class="hesabix-wc-mobile-cart__badge ms-auto text-sm hesabix-wc-fragment-mobile">%s</span>',
|
||
$b
|
||
);
|
||
|
||
$qty = WC()->cart && ! WC()->cart->is_empty() ? WC()->cart->get_cart_contents_count() : 0;
|
||
|
||
if ( $qty > 0 ) {
|
||
$fragments['.hesabix-wc-mini-cart-panel__pill'] = sprintf(
|
||
'<span class="hesabix-wc-mini-cart-panel__pill text-xs font-semibold tabular-nums px-2.5 py-1 rounded-full bg-brand-500 text-white">%s</span>',
|
||
esc_html( sprintf( __( '%s قلم', 'hesabix2' ), number_format_i18n( $qty ) ) )
|
||
);
|
||
} else {
|
||
$fragments['.hesabix-wc-mini-cart-panel__pill'] =
|
||
'<span class="hesabix-wc-mini-cart-panel__pill hesabix-wc-mini-cart-panel__pill--empty inline-block min-h-[1.5rem]" aria-hidden="true"></span>';
|
||
}
|
||
|
||
$fragments['.hesabix-wc-mini-cart__ajax'] = sprintf(
|
||
'<div class="hesabix-wc-mini-cart__ajax">%s</div>',
|
||
hesabix2_wc_get_mini_cart_inner_markup()
|
||
);
|
||
|
||
return $fragments;
|
||
}
|
||
add_filter( 'woocommerce_add_to_cart_fragments', 'hesabix2_wc_add_cart_fragments' );
|
||
|
||
/**
|
||
* آرایهٔ نانمحلی فروشگاه (یکپارچه با woocommerce.php و برگههای ثانویه).
|
||
*
|
||
* @return array<string, string>
|
||
*/
|
||
function hesabix2_wc_breadcrumb_args() {
|
||
return array(
|
||
'delimiter' => '<span class="hesabix-wc-bc-sep" aria-hidden="true">›</span>',
|
||
'wrap_before' => '<nav class="woocommerce-breadcrumb hesabix-wc-breadcrumb-nav" aria-label="' . esc_attr__( 'مسیر دسترسی', 'hesabix2' ) . '"><div class="hesabix-wc-breadcrumb__trail">',
|
||
'wrap_after' => '</div></nav>',
|
||
'before' => '',
|
||
'after' => '',
|
||
'home' => __( 'خانه', 'hesabix2' ),
|
||
);
|
||
}
|
||
|
||
/**
|
||
* ویجت ناحیهٔ کناری آرشیو فروشگاه.
|
||
*/
|
||
function hesabix2_wc_register_shop_sidebar_region() {
|
||
if ( ! hesabix2_is_woocommerce_active() ) {
|
||
return;
|
||
}
|
||
|
||
register_sidebar(
|
||
array(
|
||
'name' => __( 'فروشگاه — ستون کناری', 'hesabix2' ),
|
||
'id' => 'hesabix2-shop-sidebar',
|
||
'description' => __( 'فیلترها، جستجو و ویجتهای دستهٔ محصول؛ فقط در صفحهٔ فروشگاه و دستهها نشان داده میشود.', 'hesabix2' ),
|
||
'before_widget' => '<div id="%1$s" class="hesabix-wc-widget widget %2$s">',
|
||
'after_widget' => '</div>',
|
||
'before_title' => '<p class="hesabix-wc-widget__title widget-title">',
|
||
'after_title' => '</p>',
|
||
)
|
||
);
|
||
}
|
||
add_action( 'widgets_init', 'hesabix2_wc_register_shop_sidebar_region', 15 );
|