237 lines
8.8 KiB
PHP
237 lines
8.8 KiB
PHP
<?php
|
|
// Prevent direct access
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
use Sodino\Repositories\UpsellRepository;
|
|
use Sodino\Services\UpsellService;
|
|
|
|
global $sodino_upsell_service;
|
|
$upsellRepository = new UpsellRepository();
|
|
$sodino_upsell_service = new UpsellService($upsellRepository);
|
|
|
|
add_action('woocommerce_before_cart', 'sodino_render_upsell_suggestions');
|
|
add_action('wp_enqueue_scripts', 'sodino_enqueue_upsell_assets');
|
|
add_filter('woocommerce_add_cart_item_data', 'sodino_add_upsell_cart_item_data', 10, 4);
|
|
add_filter('woocommerce_get_cart_item_from_session', 'sodino_restore_upsell_cart_item_data', 10, 2);
|
|
add_action('woocommerce_before_calculate_totals', 'sodino_apply_upsell_cart_prices', 20);
|
|
add_filter('woocommerce_get_item_data', 'sodino_display_upsell_cart_item_data', 10, 2);
|
|
add_action('woocommerce_checkout_create_order_line_item', 'sodino_add_upsell_order_item_meta', 10, 4);
|
|
add_action('woocommerce_add_to_cart', 'sodino_track_upsell_conversion', 20, 6);
|
|
|
|
function sodino_enqueue_upsell_assets() {
|
|
if (is_admin()) {
|
|
return;
|
|
}
|
|
|
|
wp_enqueue_style('sodino-upsell-frontend', plugin_dir_url(__FILE__) . '../css/upsell-frontend.css', [], SODINO_VERSION);
|
|
}
|
|
|
|
function sodino_render_upsell_suggestions() {
|
|
if (is_admin() || !is_cart()) {
|
|
return;
|
|
}
|
|
|
|
$settings = wp_parse_args(get_option('sodino_settings', []), [
|
|
'upsell_enabled' => 1,
|
|
]);
|
|
|
|
if (empty($settings['upsell_enabled'])) {
|
|
return;
|
|
}
|
|
|
|
global $sodino_upsell_service;
|
|
if (!isset($sodino_upsell_service)) {
|
|
return;
|
|
}
|
|
|
|
$cart = WC()->cart;
|
|
if (!$cart || $cart->is_empty()) {
|
|
return;
|
|
}
|
|
|
|
$upsells = $sodino_upsell_service->getMatchingUpsells($cart);
|
|
if (empty($upsells)) {
|
|
return;
|
|
}
|
|
|
|
echo '<section class="sodino-upsell-panel" aria-label="' . esc_attr__('پیشنهادهای ویژه سودینو', 'sodino') . '">';
|
|
echo '<div class="sodino-upsell-header">';
|
|
echo '<div>';
|
|
echo '<p class="sodino-upsell-eyebrow">' . esc_html__('پیشنهاد ویژه', 'sodino') . '</p>';
|
|
echo '<h2>' . esc_html__('این پیشنهادها را با تخفیف به سبد خود اضافه کنید', 'sodino') . '</h2>';
|
|
echo '</div>';
|
|
echo '<span class="sodino-upsell-count">' . esc_html(sprintf(__('%d پیشنهاد فعال', 'sodino'), count($upsells))) . '</span>';
|
|
echo '</div>';
|
|
echo '<div class="sodino-upsell-grid">';
|
|
|
|
foreach ($upsells as $upsell) {
|
|
$product = wc_get_product($upsell->target_product_id);
|
|
if (!$product || !$product->is_purchasable() || !$product->is_in_stock() || !$product->is_type(['simple', 'variation'])) {
|
|
continue;
|
|
}
|
|
|
|
$discountedPrice = $sodino_upsell_service->applyUpsellDiscount($product, $upsell);
|
|
$originalPrice = floatval($product->get_price());
|
|
$priceHtml = wc_price($discountedPrice);
|
|
if ($discountedPrice < $originalPrice) {
|
|
$priceHtml .= ' <del>' . wc_price($originalPrice) . '</del>';
|
|
}
|
|
|
|
$addToCartUrl = sodino_get_upsell_add_to_cart_url($product, $upsell);
|
|
$image = $product->get_image('woocommerce_thumbnail', ['class' => 'sodino-upsell-image']);
|
|
$savings = max(0, $originalPrice - $discountedPrice);
|
|
$sodino_upsell_service->incrementImpression($upsell->id);
|
|
|
|
echo '<article class="sodino-upsell-card">';
|
|
echo '<div class="sodino-upsell-media">' . $image . '</div>';
|
|
echo '<div class="sodino-upsell-body">';
|
|
echo '<div class="sodino-upsell-meta">';
|
|
echo '<span>' . esc_html($sodino_upsell_service->getDiscountLabel($upsell)) . '</span>';
|
|
echo '<span>' . esc_html($sodino_upsell_service->getTriggerLabel($upsell)) . '</span>';
|
|
echo '</div>';
|
|
echo '<p class="sodino-upsell-title">' . esc_html($upsell->title) . '</p>';
|
|
echo '<h3>' . esc_html($product->get_name()) . '</h3>';
|
|
echo '<div class="sodino-upsell-footer">';
|
|
echo '<div class="sodino-upsell-price">' . $priceHtml;
|
|
if ($savings > 0) {
|
|
echo '<small>' . esc_html(sprintf(__('صرفهجویی: %s', 'sodino'), wp_strip_all_tags(wc_price($savings)))) . '</small>';
|
|
}
|
|
echo '</div>';
|
|
echo '<a href="' . esc_url($addToCartUrl) . '" class="sodino-upsell-button">' . esc_html__('افزودن با تخفیف', 'sodino') . '</a>';
|
|
echo '</div></div>';
|
|
echo '</article>';
|
|
}
|
|
|
|
echo '</div>';
|
|
echo '</section>';
|
|
}
|
|
|
|
function sodino_get_upsell_add_to_cart_url($product, $upsell) {
|
|
return add_query_arg(
|
|
[
|
|
'add-to-cart' => $product->get_id(),
|
|
'quantity' => 1,
|
|
'sodino_upsell_id' => $upsell->id,
|
|
'sodino_upsell_nonce' => wp_create_nonce('sodino_apply_upsell_' . $upsell->id),
|
|
],
|
|
wc_get_cart_url()
|
|
);
|
|
}
|
|
|
|
function sodino_add_upsell_cart_item_data($cart_item_data, $product_id, $variation_id, $quantity) {
|
|
if (empty($_REQUEST['sodino_upsell_id'])) {
|
|
return $cart_item_data;
|
|
}
|
|
|
|
$upsellId = absint(wp_unslash($_REQUEST['sodino_upsell_id']));
|
|
$nonce = sanitize_text_field(wp_unslash($_REQUEST['sodino_upsell_nonce'] ?? ''));
|
|
if (!$upsellId || !wp_verify_nonce($nonce, 'sodino_apply_upsell_' . $upsellId)) {
|
|
return $cart_item_data;
|
|
}
|
|
|
|
global $sodino_upsell_service;
|
|
if (!isset($sodino_upsell_service) || !WC()->cart) {
|
|
return $cart_item_data;
|
|
}
|
|
|
|
$upsell = $sodino_upsell_service->getById($upsellId);
|
|
if (
|
|
!$sodino_upsell_service->canApplyToProduct($upsell, $product_id, $variation_id)
|
|
|| !$sodino_upsell_service->isValidForCart($upsell, WC()->cart)
|
|
) {
|
|
return $cart_item_data;
|
|
}
|
|
|
|
$product = wc_get_product($variation_id ?: $product_id);
|
|
if (!$product) {
|
|
return $cart_item_data;
|
|
}
|
|
|
|
$originalPrice = floatval($product->get_price());
|
|
$discountedPrice = $sodino_upsell_service->calculateDiscountedPrice($originalPrice, $upsell);
|
|
|
|
$cart_item_data['sodino_upsell'] = [
|
|
'id' => (int) $upsell->id,
|
|
'title' => sanitize_text_field($upsell->title),
|
|
'discount_type' => sanitize_key($upsell->discount_type),
|
|
'discount_value' => floatval($upsell->discount_value),
|
|
'original_price' => $originalPrice,
|
|
'discounted_price' => $discountedPrice,
|
|
];
|
|
$cart_item_data['sodino_upsell_key'] = md5(wp_json_encode($cart_item_data['sodino_upsell']) . microtime(true));
|
|
|
|
return $cart_item_data;
|
|
}
|
|
|
|
function sodino_restore_upsell_cart_item_data($cart_item, $values) {
|
|
if (!empty($values['sodino_upsell'])) {
|
|
$cart_item['sodino_upsell'] = $values['sodino_upsell'];
|
|
$cart_item['sodino_upsell_key'] = $values['sodino_upsell_key'] ?? '';
|
|
}
|
|
return $cart_item;
|
|
}
|
|
|
|
function sodino_apply_upsell_cart_prices($cart) {
|
|
if (is_admin() && !defined('DOING_AJAX')) {
|
|
return;
|
|
}
|
|
|
|
if (!$cart) {
|
|
return;
|
|
}
|
|
|
|
foreach ($cart->get_cart() as $cartItem) {
|
|
if (empty($cartItem['sodino_upsell']['discounted_price']) || empty($cartItem['data'])) {
|
|
continue;
|
|
}
|
|
|
|
$cartItem['data']->set_price(max(0, floatval($cartItem['sodino_upsell']['discounted_price'])));
|
|
}
|
|
}
|
|
|
|
function sodino_display_upsell_cart_item_data($item_data, $cart_item) {
|
|
if (empty($cart_item['sodino_upsell'])) {
|
|
return $item_data;
|
|
}
|
|
|
|
$upsell = $cart_item['sodino_upsell'];
|
|
$item_data[] = [
|
|
'key' => __('پیشنهاد سودینو', 'sodino'),
|
|
'value' => esc_html($upsell['title']),
|
|
];
|
|
|
|
if (!empty($upsell['original_price']) && floatval($upsell['discounted_price']) < floatval($upsell['original_price'])) {
|
|
$item_data[] = [
|
|
'key' => __('تخفیف آپسل', 'sodino'),
|
|
'value' => wp_kses_post(wc_price(floatval($upsell['original_price']) - floatval($upsell['discounted_price']))),
|
|
];
|
|
}
|
|
|
|
return $item_data;
|
|
}
|
|
|
|
function sodino_add_upsell_order_item_meta($item, $cart_item_key, $values, $order) {
|
|
if (empty($values['sodino_upsell'])) {
|
|
return;
|
|
}
|
|
|
|
$upsell = $values['sodino_upsell'];
|
|
$item->add_meta_data('_sodino_upsell_id', (int) $upsell['id'], true);
|
|
$item->add_meta_data(__('پیشنهاد سودینو', 'sodino'), sanitize_text_field($upsell['title']), true);
|
|
$item->add_meta_data(__('قیمت اصلی آپسل', 'sodino'), wc_price(floatval($upsell['original_price'])), true);
|
|
$item->add_meta_data(__('قیمت تخفیفی آپسل', 'sodino'), wc_price(floatval($upsell['discounted_price'])), true);
|
|
}
|
|
|
|
function sodino_track_upsell_conversion($cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data) {
|
|
if (empty($cart_item_data['sodino_upsell']['id'])) {
|
|
return;
|
|
}
|
|
|
|
global $sodino_upsell_service;
|
|
if (isset($sodino_upsell_service)) {
|
|
$sodino_upsell_service->incrementConversion((int) $cart_item_data['sodino_upsell']['id']);
|
|
}
|
|
}
|