| Server IP : 104.171.130.249 / Your IP : 216.73.216.146 Web Server : nginx/1.25.5 System : Linux 0dac65491b7e 6.8.0-134-generic #134-Ubuntu SMP PREEMPT_DYNAMIC Fri Jun 26 18:43:11 UTC 2026 x86_64 User : root ( 0) PHP Version : 8.4.23 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : OFF | Perl : ON | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : /var/www/html/wp-content/themes/matreshka/woocommerce/ |
Upload File : |
<?php
/**
* Content Single Product - custom layout
*/
defined( 'ABSPATH' ) || exit;
global $product;
$product_id = $product ? $product->get_id() : 0;
$is_liked = $product_id ? matreshka_is_in_wishlist( $product_id ) : false;
$like_icon = $is_liked ? get_template_directory_uri() . '/assets/icons/Heart.svg' : get_template_directory_uri() . '/assets/icons/like.svg';
$product_title = get_the_title();
$image_url_exists = static function( $url ) {
if ( ! $url ) {
return false;
}
$uploads = wp_get_upload_dir();
if ( empty( $uploads['baseurl'] ) || empty( $uploads['basedir'] ) ) {
return true;
}
$base_url = trailingslashit( set_url_scheme( $uploads['baseurl'] ) );
$image_url = set_url_scheme( $url );
if ( strpos( $image_url, $base_url ) !== 0 ) {
return true;
}
$relative_path = substr( $image_url, strlen( $base_url ) );
$file_path = trailingslashit( $uploads['basedir'] ) . rawurldecode( $relative_path );
return file_exists( $file_path );
};
$render_product_image_slide = static function( $attachment_id, $is_main = false ) use ( $product_title, $image_url_exists ) {
$image_html = '';
$placeholder_src = wc_placeholder_img_src( 'woocommerce_single' );
if ( $attachment_id ) {
foreach ( array( 'large', 'full' ) as $image_size ) {
$image = wp_get_attachment_image_src( $attachment_id, $image_size );
if ( ! $image || empty( $image[0] ) || ! $image_url_exists( $image[0] ) ) {
continue;
}
$image_html = sprintf(
'<img width="%d" height="%d" src="%s" alt="%s" class="product-image" loading="%s" decoding="async" data-fallback-src="%s"%s>',
absint( $image[1] ),
absint( $image[2] ),
esc_url( $image[0] ),
esc_attr( $product_title ),
$is_main ? 'eager' : 'lazy',
esc_url( $placeholder_src ),
$is_main ? ' fetchpriority="high"' : ''
);
break;
}
}
if ( ! $image_html ) {
$image_html = sprintf(
'<img src="%s" alt="%s" class="product-image product-image--placeholder" loading="%s" decoding="async" data-fallback-src="%s"%s>',
esc_url( $placeholder_src ),
esc_attr( $product_title ),
$is_main ? 'eager' : 'lazy',
esc_url( $placeholder_src ),
$is_main ? ' fetchpriority="high"' : ''
);
}
echo '<div class="product-image-wrapper product-page-slide">' . $image_html . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
};
?>
<!-- Matreshka custom content-single-product loaded -->
<?php
// Bread-crumbs (desktop only) per design: Home ● Category ● Product
$primary_cat = null;
$cats = wc_get_product_terms( $product->get_id(), 'product_cat', array( 'orderby' => 'menu_order', 'order' => 'ASC' ) );
if ( ! is_wp_error( $cats ) && ! empty( $cats ) ) {
$max_depth = -1;
foreach ( $cats as $t ) {
$depth = is_taxonomy_hierarchical( 'product_cat' ) ? count( get_ancestors( $t->term_id, 'product_cat' ) ) : 0;
if ( $depth > $max_depth ) {
$max_depth = $depth;
$primary_cat = $t;
}
}
}
?>
<section class="bread-crumb d-none d-md-flex mt-4">
<div class="container">
<p class="montserrat-medium">
<a href="<?php echo esc_url( home_url( '/' ) ); ?>" class="text-decoration-none text-dark"><?php echo esc_html__( 'Главная', 'matreshka' ); ?></a>
<?php if ( $primary_cat ) : ?>
<span class="dot">●</span>
<a href="<?php echo esc_url( get_term_link( $primary_cat ) ); ?>" class="text-decoration-none text-dark"><?php echo esc_html( $primary_cat->name ); ?></a>
<?php endif; ?>
<span class="dot">●</span>
<span class="bread-crumb-product"><?php the_title(); ?></span>
</p>
</div>
</section>
<section class="d-md-none nav-container-like mt-2">
<div class="container d-flex justify-content-between align-items-center">
<a href="javascript:void(0)" class="ms-2" onclick="history.back();return false;">
<img src="<?php echo esc_url( get_template_directory_uri() . '/assets/icons/AltArrowLeft.svg' ); ?>" alt="arrow left icon">
</a>
<a href="#" class="me-2" aria-label="like" data-product-id="<?php echo esc_attr( $product_id ); ?>">
<img src="<?php echo esc_url( $like_icon ); ?>" alt="like icon" class="like-icon <?php echo $is_liked ? 'active' : ''; ?>">
</a>
</div>
</section>
<div class="product-page d-md-flex d-block">
<div class="product-row product-page-slider">
<?php
// Main image
$image_id = $product->get_image_id();
$render_product_image_slide( $image_id, true );
// Gallery images
$gallery_ids = $product->get_gallery_image_ids();
if ( ! empty( $gallery_ids ) ) {
foreach ( $gallery_ids as $gid ) {
if ( $gid ) {
$render_product_image_slide( $gid );
}
}
}
?>
</div>
<div class="product-page-info ">
<div class="product-page-titles">
<div class="d-flex justify-content-between align-items-start">
<div>
<h3 class="montserrat-bold product-page-title">
<?php the_title(); ?>
</h3>
</div>
<?php
$percentage = matreshka_get_sale_percentage( $product );
if ( $percentage ) {
echo matreshka_get_sale_badge( $product, 'single' );
} else {
?>
<a href="#" class="me-2 mt-2 d-md-block d-none" aria-label="like" data-product-id="<?php echo esc_attr( $product_id ); ?>">
<img src="<?php echo esc_url( $like_icon ); ?>" alt="like icon" class="like-icon <?php echo $is_liked ? 'active' : ''; ?>" style="width: 30px; height: 30px; max-width: none;">
</a>
<?php
}
?>
</div>
<?php
// Динамичный лейбл под заголовком из краткого описания товара
$short_label = $product->get_short_description();
// Применяем стандартный фильтр Woo и чистим теги для безопасного вывода внутри <h6>
$short_label = apply_filters( 'woocommerce_short_description', $short_label );
$short_label = trim( wp_strip_all_tags( (string) $short_label ) );
if ( $short_label === '' ) {
$short_label = esc_html__( 'Цена за 1 кг', 'matreshka' );
}
?>
<h6 class="montserrat-medium product-page-text"><?php echo esc_html( $short_label ); ?></h6>
<?php wc_get_template( 'single-product/price.php' ); ?>
<?php woocommerce_template_single_add_to_cart(); ?>
</div>
<div class="product-page-description">
<div class="first">
<h6 class="montserrat-bold ">Описание</h6>
<?php
// Полный контент (с форматированием)
$full_content = apply_filters( 'the_content', get_post_field( 'post_content', get_the_ID() ) );
// Текст без HTML для превью
$plain_text = trim( wp_strip_all_tags( $full_content ) );
$strlen = function_exists( 'mb_strlen' ) ? mb_strlen( $plain_text ) : strlen( $plain_text );
$substr = function_exists( 'mb_substr' ) ? 'mb_substr' : 'substr';
$limit = 250;
$is_long = $strlen > $limit;
$preview_text = $is_long ? $substr( $plain_text, 0, $limit ) . '…' : $plain_text;
?>
<div class="montserrat-regular product-description">
<?php if ( $is_long ) : ?>
<p class="desc-preview"><?php echo esc_html( $preview_text ); ?></p>
<div class="desc-full" style="display:none;">
<?php echo $full_content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</div>
<?php else : ?>
<div class="desc-full">
<?php echo $full_content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</div>
<?php endif; ?>
</div>
<?php if ( $is_long ) : ?>
<button class="btn btn-link montserrat-bold js-desc-toggle" type="button">Показать полностью</button>
<?php endif; ?>
</div>
<div class="nutritional-value second">
<h6 class="montserrat-semibold">Пищевая ценность на 100 г</h6>
<div class="nutritional-value-colums">
<?php
// Выводим ACF поля, только если заполнены
$nutri = array(
'proteins' => get_field( 'proteins', $product->get_id() ),
'fats' => get_field( 'fats', $product->get_id() ),
'carbs' => get_field( 'carbs', $product->get_id() ),
'calories' => get_field( 'calories', $product->get_id() ),
);
$labels = array(
'proteins' => get_field( 'proteins_label', $product->get_id() ) ?: 'Белки',
'fats' => get_field( 'fats_label', $product->get_id() ) ?: 'Жиры',
'carbs' => get_field( 'carbs_label', $product->get_id() ) ?: 'Углеводы',
'calories' => get_field( 'calories_label', $product->get_id() ) ?: 'Ккал',
);
foreach ( $nutri as $key => $val ) {
if ( isset( $val ) && $val !== '' ) {
echo '<div class="montserrat-bold">' . esc_html( $val ) . '<p class="montserrat-semibold">' . esc_html( $labels[ $key ] ) . '</p></div>';
}
}
?>
</div>
</div>
<div class="product-characteristics third">
<?php
$chars = array(
'weight' => 'Вес',
'storage_life' => 'Срок хранения',
'storage' => 'Условия хранения',
'country' => 'Страна производства',
);
foreach ( $chars as $field => $label ) {
$val = get_field( $field, $product->get_id() );
if ( isset( $val ) && $val !== '' ) {
echo '<div class="characteristic-item">';
echo '<p class="montserrat-semibold">' . esc_html( $label ) . '</p>';
echo '<span class="w-100"></span>';
echo '<p class="montserrat-medium">' . esc_html( $val ) . '</p>';
echo '</div>';
}
}
?>
</div>
<div class="alert alert-secondary montserrat-medium" role="alert">
<img src="<?php echo esc_url( get_template_directory_uri() . '/assets/icons/InfoCircle.svg' ); ?>" alt="info circle icon" class="me-2">
<p>Информация на упаковке может отличаться в зависимости от производителя</p>
</div>
<p class="montserrat-medium product-disclaimer">Вид товара может отличаться от представленных фотографий</p>
</div>
</div>
</div>