Orgsteklo/wp-content/themes/orgsteklo/woocommerce/content-single-product.php
Jamil-Abdullayev b8246597d4 Initial commit: orgsteklo WordPress theme
Custom WooCommerce theme for orgsteklo.ru including:
- Product catalog with category/subcategory hierarchy
- Custom checkout with delivery calculation
- Price calculator
- Admin settings panel
- Search functionality
- User account pages
2026-03-05 00:48:06 +04:00

432 lines
26 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
defined( 'ABSPATH' ) || exit;
global $product;
$status_text = ''; // <-- добавлено: инициализация переменной, чтобы не было Warning
do_action( 'woocommerce_before_single_product' );
if ( post_password_required() ) {
echo get_the_password_form();
return;
}
?>
<nav class="breadcumbs container">
<ul>
<li><a href="<?php echo esc_url(home_url('/')); ?>">Главная</a></li>
<li><p class="breadcumbs-separator">/</p></li>
<li><a href="<?php echo esc_url(get_permalink(wc_get_page_id('shop'))); ?>">Каталог</a></li>
<?php
global $post;
$terms = get_the_terms($post->ID, 'product_cat');
if ($terms && !is_wp_error($terms)) {
$shown = [];
foreach ($terms as $term) {
$ancestors = get_ancestors($term->term_id, 'product_cat');
$ancestors = array_reverse($ancestors);
foreach ($ancestors as $ancestor_id) {
if (in_array($ancestor_id, $shown)) continue;
$ancestor = get_term($ancestor_id, 'product_cat');
echo '<li><p class="breadcumbs-separator">/</p></li>';
echo '<li><a href="' . esc_url(get_term_link($ancestor)) . '">' . esc_html($ancestor->name) . '</a></li>';
$shown[] = $ancestor_id;
}
if (!in_array($term->term_id, $shown)) {
echo '<li><p class="breadcumbs-separator">/</p></li>';
echo '<li><a href="' . esc_url(get_term_link($term)) . '">' . esc_html($term->name) . '</a></li>';
$shown[] = $term->term_id;
}
}
}
?>
<li><p class="breadcumbs-separator">/</p></li>
<li><p><?php the_title(); ?></p></li>
</ul>
</nav>
<section class="product_page">
<div class="product_page-container container">
<div class="product_page-main">
<div class="product_page-images">
<div class="product_page-labels">
<?php
global $product;
$custom_status = get_post_meta($product->get_id(), '_custom_stock_status', true);
if ($custom_status) {
$status_text = '';
switch ($custom_status) {
case 'in_stock':
$status_text = 'В наличии';
break;
case 'low_stock':
$status_text = 'Осталось мало';
break;
case 'on_order':
$status_text = 'Под заказ';
break;
}
if ($status_text) : ?>
<div class="product_page-aviable">
<p><?php echo esc_html($status_text); ?></p>
</div>
<?php endif;
}
?>
<?php
// Получаем отсортированные теги (сначала статус, потом скидки)
$sorted_tags = get_sorted_product_tags( get_the_ID() );
// Выводим все метки (статусные и скидки)
// Теперь метки со скидками автоматически применяют скидку к цене через хуки
foreach ( $sorted_tags as $tag ) {
$is_discount = is_discount_tag( $tag->name );
$class = $is_discount ? 'product_page-discount' : 'product_page-popular';
echo '<p class="' . esc_attr( $class ) . '">' . esc_html( $tag->name ) . '</p>';
}
?>
</div>
<?php get_template_part( 'woocommerce/single-product/product', 'image' ); ?>
</div>
<div class="product_page-col">
<?php
if ($status_text) : ?>
<div class="product_page-aviable">
<p><?php echo esc_html($status_text); ?></p>
</div>
<?php endif;
?>
<h2><?php the_title(); ?></h2>
<?php
$sku = $product->get_sku();
if ($sku) : ?>
<div class="product_page-sku">
<p>Код товара:</p>
<p><?php echo esc_html($sku); ?></p>
</div>
<?php endif; ?>
<?php
global $product;
$show_specs = ( $product instanceof WC_Product ) && $product->is_type( 'simple' );
if ( $show_specs ) {
/** ===== Длина */
$len_mm_meta = get_post_meta( $product->get_id(), '_variation_length', true );
if ( $len_mm_meta !== '' ) {
$len_mm_num = floatval( str_replace( ',', '.', preg_replace( '/\x{00A0}|\s/u', '', (string) $len_mm_meta ) ) );
$length_label = $len_mm_num > 0 ? number_format_i18n( $len_mm_num, 0 ) . ' мм' : '';
} else {
$len_sys = $product->get_length();
if ( $len_sys !== '' ) {
$unit = get_option( 'woocommerce_dimension_unit', 'cm' ); // 'mm','cm','m','in','yd'
$length_label = wc_format_localized_decimal( $len_sys ) . ' ' . $unit;
} else {
$length_label = '';
}
}
/** ===== Вес (3 знака, точка, всегда "кг") */
$weight_raw = $product->get_weight();
if ( $weight_raw !== '' ) {
$weight_num = (float) wc_format_decimal( $weight_raw );
$weight = number_format( $weight_num, 3, '.', '' ) . ' кг';
} else {
$weight = '';
}
/** ===== Атрибуты */
$attrs = $product->get_attributes();
// Собираем приоритетный диаметр и остаток
$diam_vn_html = ''; // diametr-vnesnij-vnutrennij
$diam_fallback = ''; // diametr (если нет основного)
$remaining_rows = [];
if ( ! empty( $attrs ) ) {
foreach ( $attrs as $attr ) {
if ( method_exists( $attr, 'get_visible' ) && ! $attr->get_visible() ) {
continue;
}
$raw_name = $attr->get_name();
$slug = $attr->is_taxonomy()
? wc_sanitize_taxonomy_name( str_replace( 'pa_', '', $raw_name ) )
: wc_sanitize_taxonomy_name( $raw_name );
// Пропускаем вес (ves) полностью — он выводится отдельно
if ( $slug === 'ves' ) {
continue;
}
// Получаем значение и метку
if ( $attr->is_taxonomy() ) {
$values = wc_get_product_terms(
$product->get_id(),
$attr->get_name(),
[ 'fields' => 'names' ]
);
$value = $values ? implode( ', ', $values ) : '';
$label = wc_attribute_label( $attr->get_name() );
} else {
$options = (array) $attr->get_options();
$options = array_map( static function( $v ) { return wp_kses_post( $v ); }, $options );
$value = $options ? implode( ', ', $options ) : '';
$label = wc_attribute_label( $attr->get_name() );
}
if ( $value === '' ) {
continue;
}
$row_html = '<div class="product-specs__row">
<span class="product-specs__label">' . esc_html( $label ) . ':</span>
<span class="product-specs__value">' . esc_html( $value ) . '</span>
</div>';
// Приоритет: diametr-vnesnij-vnutrennij → затем diametr
if ( $slug === 'diametr-vnesnij-vnutrennij' ) {
$diam_vn_html = $row_html;
continue; // не добавляем в остаток
}
if ( $slug === 'diametr' ) {
$diam_fallback = $row_html;
continue; // не добавляем в остаток
}
// Остальные атрибуты — в конец
$remaining_rows[] = $row_html;
}
}
// Печатаем блок, если есть что выводить
if ( $diam_vn_html || $diam_fallback || $length_label !== '' || $weight !== '' || ! empty( $remaining_rows ) ) :
?>
<div class="product-specs">
<div class="product-specs__list">
<?php
// 1) Диаметр (внешний/внутренний), если нет — обычный диаметр
echo $diam_vn_html ? $diam_vn_html : $diam_fallback;
// 2) Длина
if ( $length_label !== '' ) : ?>
<div class="product-specs__row">
<span class="product-specs__label">Длина:</span>
<span class="product-specs__value"><?php echo esc_html( $length_label ); ?></span>
</div>
<?php endif; ?>
<!-- 3) Вес 1 шт -->
<?php
// Для вариативных товаров не показываем (есть в селекте "Вес 1 шт")
// Для простых товаров - показываем
if ( $weight !== '' && ! $product->is_type('variable') ) :
?>
<div class="product-specs__row">
<span class="product-specs__label">Вес 1&nbsp;шт:</span>
<span class="product-specs__value"><?php echo esc_html( $weight ); ?></span>
</div>
<?php endif; ?>
<!-- 4) Цена 1 шт -->
<div class="product-specs__row">
<span class="product-specs__label">Цена 1&nbsp;шт:</span>
<span class="product-specs__value" style="color: var(--Blue);">
<?php
$price = (float) $product->get_price();
$regular_price = (float) $product->get_regular_price();
// Сначала текущая цена
echo number_format_i18n( $price, 0 ) . ' ₽';
// Потом зачёркнутая цена (если есть скидка)
if ( $product->is_on_sale() && $regular_price > $price ) {
echo '<span style="text-decoration: line-through; color: #999; margin-left: 8px;">';
echo number_format_i18n( $regular_price, 0 ) . ' ₽';
echo '</span>';
}
?>
</span>
</div>
<?php
// 5) Остальные атрибуты (кроме ves, diametr-vnesnij-vnutrennij, diametr)
if ( ! empty( $remaining_rows ) ) {
echo implode( '', $remaining_rows );
}
?>
</div>
</div>
<style>
.product-specs {margin-bottom: 16px;}
.product-specs__list {display: flex; flex-direction: column;}
.product-specs__row {display: flex; align-items: baseline; gap: 8px;}
.product-specs__label {
color: var(--Grey-2);
font-size: 1.4rem;
font-weight: 600;
line-height: 130%;
letter-spacing: -0.028rem;
}
.product-specs__value { color: var(--Black); font-weight: 600; }
</style>
<?php
endif;
}
?>
<?php do_action( 'woocommerce_single_product_summary' ); ?>
</div>
</div>
<div class="product_page-info">
<div class="product_page-tabs">
<button class="product_page-tab active">Характеристики</button>
<?php
$product_description = get_field('product_description');
$documentation_repeat_repeats = get_field('documentation_repeat_repeat');
if($product_description) {
echo '<button class="product_page-tab">Область применения</button>';
}
if($documentation_repeat_repeats) {
echo '<button class="product_page-tab">Документация</button>';
}
?>
</div>
<div class="product_page-tabs__mob">
<button class="product_page-tabs__mob-button">
<p>Характеристики</p>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M11.9485 5.45312H7.79512H4.05512C3.41512 5.45312 3.09512 6.22646 3.54845 6.67979L7.00179 10.1331C7.55512 10.6865 8.45512 10.6865 9.00845 10.1331L10.3218 8.81979Л12.4618 6.67979C12.9085 6.22646 12.5885 5.45312 11.9485 5.45312Z" fill="#2C3846"/></svg>
</button>
<div class="product_page-tabs__mob-content">
<button class="product_page-tabs__mob-tab">
<p>Характеристики</p>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M7.99967 1.33325C4.32634 1.33325 1.33301 4.32659 1.33301 7.99992C1.33301 11.6733 4.32634 14.6666 7.99967 14.6666C11.673 14.6666 14.6663 11.6733 14.6663 7.99992C14.6663 4.32659 11.673 1.33325 7.99967 1.33325ZM11.1863 6.46659L7.40634 10.2466C7.31301 10.3399 7.18634 10.3933 7.05301 10.3933C6.91967 10.3933 6.79301 10.3399 6.69967 10.2466L4.81301 8.35992C4.61967 8.16659 4.61967 7.84659 4.81301 7.65325C5.00634 7.45992 5.32634 7.45992 5.51967 7.65325L7.05301 9.18659L10.4797 5.75992C10.673 5.56659 10.993 5.56659 11.1863 5.75992C11.3797 5.95325 11.3797 6.26659 11.1863 6.46659Z" fill="#02ADEF"/></svg>
</button>
<?php
if($product_description) {
echo '<button class="product_page-tabs__mob-tab"><p>Область применения</p><svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M7.99967 1.33325C4.32634 1.33325 1.33301 4.32659 1.33301 7.99992C1.33301 11.6733 4.32634 14.6666 7.99967 14.6666C11.673 14.6666 14.6663 11.6733 14.6663 7.99992C14.6663 4.32659 11.673 1.33325 7.99967 1.33325ZM11.1863 6.46659L7.40634 10.2466C7.31301 10.3399 7.18634 10.3933 7.05301 10.3933C6.91967 10.3933 6.79301 10.3399 6.69967 10.2466L4.81301 8.35992C4.61967 8.16659 4.61967 7.84659 4.81301 7.65325C5.00634 7.45992 5.32634 7.45992 5.51967 7.65325L7.05301 9.18659L10.4797 5.75992C10.673 5.56659 10.993 5.56659 11.1863 5.75992C11.3797 5.95325 11.3797 6.26659 11.1863 6.46659Z" fill="#02ADEF"/></svg></button>';
}
if($documentation_repeat_repeats) {
echo '<button class="product_page-tabs__mob-tab"><p>Документация</p><svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M7.99967 1.33325C4.32634 1.33325 1.33301 4.32659 1.33301 7.99992C1.33301 11.6733 4.32634 14.6666 7.99967 14.6666C11.673 14.6666 14.6663 11.6733 14.6663 7.99992C14.6663 4.32659 11.673 1.33325 7.99967 1.33325ZM11.1863 6.46659Л7.40634 10.2466C7.31301 10.3399 7.18634 10.3933 7.05301 10.3933C6.91967 10.3933 6.79301 10.3399 6.69967 10.2466L4.81301 8.35992C4.61967 8.16659 4.61967 7.84659 4.81301 7.65325C5.00634 7.45992 5.32634 7.45992 5.51967 7.65325L7.05301 9.18659Л10.4797 5.75992C10.673 5.56659 10.993 5.56659 11.1863 5.75992C11.3797 5.95325 11.3797 6.26659 11.1863 6.46659Z" fill="#02ADEF"/></svg></button>';
}
?>
</div>
</div>
<div class="product_page-content active">
<div class="product_page-description">
<h2>Характеристики и свойства</h2>
<div class="product_page-description-col">
<?php echo the_content(); ?>
</div>
</div>
</div>
<?php
if($product_description) {
echo '<div class="product_page-content"><div class="product_page-description"><h2>Область применения</h2><div class="product_page-description-col">' . $product_description . '</div></div></div>';
}
if($documentation_repeat_repeats) {
echo '<div class="product_page-content"><div class="product_page-docs"><h2>Документация для скачивания</h2><div class="product_page-docs__grid">';
foreach ($documentation_repeat_repeats as $index => $documentation_repeat_repeat) {
$documentation_repeat_repeat_title = $documentation_repeat_repeat['documentation_repeat_repeat_title'];
$documentation_repeat_repeat_format = $documentation_repeat_repeat['documentation_repeat_repeat_format'];
$documentation_repeat_repeat_razmer = $documentation_repeat_repeat['documentation_repeat_repeat_razmer'];
$documentation_repeat_repeat_file = $documentation_repeat_repeat['documentation_repeat_repeat_file'];
$documentation_repeat_repeat_file_url = $documentation_repeat_repeat_file ? esc_url($documentation_repeat_repeat_file['url']) : '';
echo '<div class="documentation-item">';
echo '<a href="' . $documentation_repeat_repeat_file_url . '" class="documentation-item__title">' . $documentation_repeat_repeat_title . '</a>';
echo '<div class="documentation-item__row">';
echo '<div class="documentation-item__info">';
if($documentation_repeat_repeat_format) {
echo '<p>' . $documentation_repeat_repeat_format . '</p>';
}
if($documentation_repeat_repeat_razmer) {
echo '<p>' . $documentation_repeat_repeat_razmer . '</p>';
}
echo '</div>';
echo '<a href="' . $documentation_repeat_repeat_file_url . '" class="documentation-item__download" download=""><svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#clip0_3011_8559)"><path d="M6.58516 12.0813C6.77089 12.2672 6.99143 12.4146 7.23416 12.5152C7.4769 12.6158 7.73707 12.6676 7.99983 12.6676C8.26258 12.6676 8.52275 12.6158 8.76549 12.5152C9.00822 12.4146 9.22876 12.2672 9.41449 12.0813L11.5552 9.94067C11.6699 9.81373 11.7315 9.64752 11.7271 9.47644C11.7227 9.30536 11.6527 9.14253 11.5316 9.02165C11.4104 8.90077 11.2474 8.8311 11.0764 8.82707C10.9053 8.82304 10.7392 8.88496 10.6125 9L8.66182 10.9513L8.66649 0.666667C8.66649 0.489856 8.59625 0.320286 8.47123 0.195262C8.34621 0.0702379 8.17664 0 7.99983 0V0C7.82301 0 7.65344 0.0702379 7.52842 0.195262C7.4034 0.320286 7.33316 0.489856 7.33316 0.666667L7.32716 10.9387L5.38716 9C5.26206 8.875 5.09244 8.8048 4.91559 8.80486C4.73874 8.80493 4.56916 8.87524 4.44416 9.00033C4.31915 9.12543 4.24896 9.29506 4.24902 9.4719C4.24909 9.64875 4.3194 9.81833 4.44449 9.94333L6.58516 12.0813Z" fill="#02ADEF"/><path d="M15.3333 10.6665C15.1565 10.6665 14.987 10.7367 14.8619 10.8618C14.7369 10.9868 14.6667 11.1564 14.6667 11.3332V13.9998C14.6667 14.1766 14.5964 14.3462 14.4714 14.4712C14.3464 14.5963 14.1768 14.6665 14 14.6665H2C1.82319 14.6665 1.65362 14.5963 1.5286 14.4712C1.40357 14.3462 1.33333 14.1766 1.33333 13.9998V11.3332C1.33333 11.1564 1.2631 10.9868 1.13807 10.8618C1.01305 10.7367 0.843478 10.6665 0.666667 10.6665C0.489856 10.6665 0.320286 10.7367 0.195262 10.8618C0.0702379 10.9868 0 11.1564 0 11.3332L0 13.9998C0 14.5303 0.210714 15.039 0.585786 15.414C0.960859 15.7891 1.46957 15.9998 2 15.9998H14C14.5304 15.9998 15.0391 15.7891 15.4142 15.414C15.7893 15.039 16 14.5303 16 13.9998V11.3332C16 11.1564 15.9298 10.9868 15.8047 10.8618C15.6797 10.7367 15.5101 10.6665 15.3333 10.6665Z" fill="#02ADEF"/></g><defs><clipPath id="clip0_3011_8559"><rect width="16" height="16" fill="white"/></clipPath></defs></svg></a>'; // оставить SVG как есть
echo '</div>';
echo '<div class="documentation-item__mob">';
echo '<a href="' . esc_url($documentation_repeat_repeat_file['url']) . '" class="documentation-item__title">' . $documentation_repeat_repeat_title . '</a>';
echo '<div class="documentation-item__info">';
if($documentation_repeat_repeat_format) {
echo '<p>' . $documentation_repeat_repeat_format . '</p>';
}
if($documentation_repeat_repeat_razmer) {
echo '<p>' . $documentation_repeat_repeat_razmer . '</p>';
}
echo '</div>';
echo '</div>';
echo '</div>';
}
echo '</div></div></div>';
}
?>
</div>
</div>
</section>
<?php
global $product;
$categories = wp_get_post_terms( $product->get_id(), 'product_cat', array( 'fields' => 'ids' ) );
// Расширяем до родительской категории и всех её дочерних
$all_categories = $categories;
foreach ( $categories as $cat_id ) {
$ancestors = get_ancestors( $cat_id, 'product_cat' );
$all_categories = array_merge( $all_categories, $ancestors );
foreach ( $ancestors as $ancestor_id ) {
$children = get_term_children( $ancestor_id, 'product_cat' );
$all_categories = array_merge( $all_categories, $children );
}
}
$categories = array_unique( $all_categories );
// Рекомендуемые товары: только с _is_recommended_product = 'yes' из той же категории
$recommended_args = array(
'post_type' => 'product',
'posts_per_page' => 8,
'post__not_in' => array( $product->get_id() ),
'ignore_sticky_posts' => 1,
'post_status' => array( 'publish', 'draft' ),
'orderby' => 'rand',
'meta_query' => array(
array(
'key' => '_is_recommended_product',
'value' => 'yes',
),
),
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => $categories,
'operator' => 'IN',
),
),
);
$recommended_query = new WP_Query( $recommended_args );
$all_products = $recommended_query->posts;
if ( ! empty( $all_products ) ) :
global $post;
echo '<section class="cart_more"><div class="cart_more-container container"><div class="cart_more-name"><h2>Рекомендуемые товары</h2><a href="/catalog" class="cart_more-link">Все товары<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M15.0007 9.99989C14.9966 9.56147 14.8199 9.14231 14.509 8.83323L10.934 5.2499C10.7778 5.09469 10.5666 5.00757 10.3465 5.00757C10.1263 5.00757 9.91512 5.09469 9.75898 5.2499C9.68088 5.32736 9.61888 5.41953 9.57657 5.52108C9.53427 5.62263 9.51249 5.73155 9.51249 5.84156C9.51249 5.95157 9.53427 6.06049 9.57657 6.16204C9.61888 6.26359 9.68088 6.35576 9.75898 6.43323L12.5007 9.16656H4.16732C3.9463 9.16656 3.73434 9.25435 3.57806 9.41064C3.42178 9.56692 3.33398 9.77888 3.33398 9.99989C3.33398 10.2209 3.42178 10.4329 3.57806 10.5891C3.73434 10.7454 3.9463 10.8332 4.16732 10.8332H12.5007L9.75898 13.5749C9.60206 13.7307 9.51347 13.9425 9.51269 14.1636C9.51191 14.3847 9.599 14.5971 9.75482 14.7541C9.91063 14.911 10.1224 14.9996 10.3435 15.0003C10.5647 15.0011 10.7771 14.914 10.934 14.7582L14.509 11.1749C14.822 10.8638 14.9988 10.4412 15.0007 9.99989Z" fill="#02ADEF"/></svg></a></div><div class="products-slider"><div class="products-swiper swiper"><div class="swiper-wrapper">';
foreach ( $all_products as $related_product ) :
$post = $related_product;
setup_postdata( $post );
echo '<div class="swiper-slide">';
wc_get_template_part( 'content', 'product' );
echo '</div>';
endforeach;
wp_reset_postdata();
echo '</div></div><button class="products-prev"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M10.0596 13.28L5.7129 8.9333C5.19957 8.41997 5.19957 7.57997 5.7129 7.06664L10.0596 2.71997" stroke="white" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/></svg></button><button class="products-next"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M5.94043 13.28L10.2871 8.9333C10.8004 8.41997 10.8004 7.57997 10.2871 7.06664L5.94043 2.71997" stroke="white" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/></svg></button></div><div class="cart_more-mob"><div class="products-mob">';
foreach ( $all_products as $related_product ) :
$post = $related_product;
setup_postdata( $post );
wc_get_template_part( 'content', 'product' );
endforeach;
wp_reset_postdata();
echo '</div><a href="/catalog" class="cart_more-mob__link">Все товары</a></div></div></section>';
endif;
?>