'product', 'post_status' => 'publish', 'posts_per_page' => $posts_per_page, 'paged' => $context['get_page'], 'has_password' => FALSE ); $count_args = array( 'post_type' => 'product', 'post_status' => 'publish', 'posts_per_page' => -1, 'has_password' => FALSE ); if ($context['get_category'] != NULL) { $categories = [ 'tax_query' => array( array( 'taxonomy' => $context['get_category_type'], 'field' => 'term_id', 'terms' => array($context['get_category']), 'operator' => 'IN' ), array( 'taxonomy' => 'product_visibility', 'field' => 'slug', 'terms' => 'exclude-from-catalog', 'operator' => 'NOT IN' ) ) ]; $args = array_merge($args, $categories); $count_args = array_merge($count_args, $categories); } $products = new WP_Query($args); $products = new Timber\PostQuery($products, 'Timber\Integrations\WooCommerce\Product'); $context['posts'] = $products; $context['count'] = count(Timber::get_posts($count_args)); if ($context['count'] <= $context['get_page'] * $posts_per_page) { $context['ended'] = true; } Timber::render( '_blocks/shop/archive-product-ajaxload.twig', $context ); die(); } //Получить аттрибуты товара по ID function get_product_info ($id, $type) { if (!$id) { return ''; } $product = wc_get_product($id); $custom_measurement = get_post_meta($id, '_custom_measurement', true) ?: pll__('кг'); $custom_size = get_post_meta($id, '_size_for_display', true) ?: ''; if (!$product) { return ''; } if ($type == 'price') { return $product->get_price(); } elseif ($type == 'weight') { if ($custom_size){ return $custom_size ? $custom_size . ' ' . $custom_measurement : '';; } else{ return $product->get_weight() ? $product->get_weight() . ' ' . $custom_measurement : ''; } } return ''; } //Кнопка добавления в корзину function get_add_to_cart_button ($id) { $product = wc_get_product( $id ); return ''. pll__('Добавить в корзину') .''; } //Получить товары из одной подборки по весу function get_collection_siblings($term) { if (!$term) { return []; } $args = array( 'posts_per_page' => -1, 'post_type' => 'product', 'order' => 'ASC', 'orderby' => 'name', // Fixed parameter name (was 'order_by') 'tax_query' => [ [ 'taxonomy' => 'pa_collection', 'terms' => $term, 'field' => 'id', ] ], ); $siblings = get_posts($args); // Create array with products and their weights $siblings_with_weights = []; foreach ($siblings as $sibling) { $weight = function_exists('get_product_info') ? get_product_info($sibling->ID, 'weight') : 0; $siblings_with_weights[] = [ 'post' => $sibling, 'weight' => floatval($weight) // Ensure weight is treated as a number ]; } // Sort by weight usort($siblings_with_weights, function($a, $b) { return $a['weight'] <=> $b['weight']; }); // Extract just the posts in sorted order $sorted_siblings = array_map(function($item) { return $item['post']; }, $siblings_with_weights); return $sorted_siblings; } add_filter( 'woocommerce_price_trim_zeros', '__return_true' ); // Функция для округления цен с учетом налога function round_price_with_tax($price) { return round($price); } // Функция для получения цены товара с учетом налога и округления function get_product_price_with_tax($product) { if (!$product) return 0; $price = $product->get_price(); $tax_rate = 0; // Получаем ставку налога для товара $tax_rates = WC_Tax::get_rates($product->get_tax_class()); if (!empty($tax_rates)) { $tax_rate = array_values($tax_rates)[0]['rate'] ?? 0; } // Вычисляем цену с налогом $price_with_tax = $price * (1 + $tax_rate / 100); return round_price_with_tax($price_with_tax); } // Функция для получения общей суммы корзины с учетом налога и округления function get_cart_total_with_tax() { if (!WC()->cart) return 0; $total = WC()->cart->get_total('edit'); return round_price_with_tax($total); } // Функция для получения стоимости доставки с учетом налога и округления function get_shipping_total_with_tax() { if (!WC()->cart) return 0; $shipping_total = WC()->cart->get_shipping_total(); return round_price_with_tax($shipping_total); } // Добавление поля для выбора рекомендуемых товаров function register_recommended_products_acf_field() { if (function_exists('acf_add_local_field_group')) { acf_add_local_field_group(array( 'key' => 'group_recommended_products', 'title' => 'Рекомендуемые товары', 'fields' => array( array( 'key' => 'field_recommended_products', 'label' => 'Выберите рекомендуемые товары', 'name' => 'recommended_products', 'type' => 'relationship', 'instructions' => 'Выберите товары, которые будут отображаться в секции "вашему питомцу может понравиться"', 'required' => 0, 'conditional_logic' => 0, 'post_type' => array( 0 => 'product', ), 'filters' => array( 0 => 'search', 1 => 'taxonomy', ), 'return_format' => 'object', 'min' => '', 'max' => 8, ), ), 'location' => array( array( array( 'param' => 'post_type', 'operator' => '==', 'value' => 'product', ), ), ), 'menu_order' => 0, 'position' => 'normal', 'style' => 'default', 'label_placement' => 'top', 'instruction_placement' => 'label', 'hide_on_screen' => '', )); } } add_action('acf/init', 'register_recommended_products_acf_field'); add_action('wp_footer', 'remove_view_cart_button_js'); function remove_view_cart_button_js() { ?> managing_stock()) { return $passed; } $stock = $product->get_stock_quantity(); $in_cart = WC()->cart->get_cart_item_quantities(); $already_in_cart = $in_cart[$product->get_id()] ?? 0; $total = $already_in_cart + $quantity; if ($total > $stock) { $can_add = max($stock - $already_in_cart, 0); if ($can_add > 0) { // Добавим максимум WC()->cart->add_to_cart($product_id, $can_add, $variation_id, $variations); wc_add_notice(sprintf( __('Вы запросили %d шт., но доступно только %d. Добавлено максимально возможное количество.', 'woocommerce'), $quantity, $can_add ), 'notice'); } else { wc_add_notice(__('Вы не можете добавить больше — товар закончился на складе.', 'woocommerce'), 'error'); } // Возвращаем false, чтобы остановить оригинальное добавление return false; } return $passed; } // Убираем редирект на страницу товара при неудаче добавления add_filter('woocommerce_cart_redirect_after_error', '__return_false'); add_action('wp_ajax_get_wc_notices', 'custom_get_wc_notices'); add_action('wp_ajax_nopriv_get_wc_notices', 'custom_get_wc_notices'); add_action('woocommerce_after_cart_item_quantity_update', 'custom_limit_cart_quantity_on_update', 20, 4); function custom_limit_cart_quantity_on_update($cart_item_key, $quantity, $old_quantity, $cart) { $cart_item = $cart->get_cart_item($cart_item_key); if (!$cart_item) { return; } $product = $cart_item['data']; if (!$product->managing_stock()) { return; } $stock = $product->get_stock_quantity(); if ($quantity > $stock) { // Ограничим до доступного количества $cart->set_quantity($cart_item_key, $stock); wc_add_notice(sprintf( __('Вы запросили %d шт., но доступно только %d. Количество было скорректировано.', 'woocommerce'), $quantity, $stock ), 'notice'); } } function custom_get_wc_notices() { ob_start(); wc_print_notices(); // выводим уведомления, если они есть $html = ob_get_clean(); wp_send_json_success([ 'html' => $html, ]); }