1105 lines
50 KiB
PHP
1105 lines
50 KiB
PHP
<?php
|
||
/*
|
||
Template Name: Шаблон страницы Лагерь
|
||
|
||
Все данные организации теперь в ACF «Настройки филиала» (меню слева, под Консолью).
|
||
Поля контента страницы (hero, about, programs, mentors, faq, etc.) — в Carbon Fields в метабоксе ниже.
|
||
*/
|
||
add_filter( 'wpseo_json_ld_output', '__return_false' );
|
||
add_filter( 'wpseo_opengraph_type', function( $type ) {
|
||
if ( is_page_template( 'page-camp.php' ) ) {
|
||
return 'website';
|
||
}
|
||
return $type;
|
||
} );
|
||
add_filter( 'wpseo_frontend_presenter_classes', function( $presenters ) {
|
||
if ( is_page_template( 'page-camp.php' ) ) {
|
||
$presenters = array_filter( $presenters, function( $p ) {
|
||
return strpos( $p, 'Article_Modified_Time' ) === false
|
||
&& strpos( $p, 'Article_Published_Time' ) === false
|
||
&& strpos( $p, 'Article_Author' ) === false
|
||
&& strpos( $p, 'Article_Publisher' ) === false
|
||
&& strpos( $p, 'Label1' ) === false
|
||
&& strpos( $p, 'Data1' ) === false;
|
||
} );
|
||
}
|
||
return $presenters;
|
||
} );
|
||
// Убираем twitter:label1 / twitter:data1 (наследие article-режима)
|
||
add_filter( 'wpseo_twitter_label1', '__return_empty_string' );
|
||
add_filter( 'wpseo_twitter_data1', '__return_empty_string' );
|
||
|
||
// Добавляем og:image:alt из featured image (совпадает с og:image от Yoast)
|
||
add_action( 'wp_head', function() {
|
||
if ( ! is_page_template( 'page-camp.php' ) ) return;
|
||
$thumb_id = get_post_thumbnail_id( get_queried_object_id() );
|
||
if ( $thumb_id ) {
|
||
$alt = get_post_meta( $thumb_id, '_wp_attachment_image_alt', true );
|
||
if ( $alt ) {
|
||
echo '<meta property="og:image:alt" content="' . esc_attr( $alt ) . '" />' . "\n";
|
||
}
|
||
}
|
||
}, 1 );
|
||
|
||
add_action('wp_head', function() { echo '<style>.hidden{display:none}</style>'; }, 100);
|
||
get_header();
|
||
?>
|
||
<?php
|
||
$post_id = get_the_ID();
|
||
$theme_uri = get_template_directory_uri();
|
||
|
||
// ─── ДАННЫЕ ОРГАНИЗАЦИИ: ───
|
||
$opt_city_prep = get_option( 'branch_city_prep' ) ?: get_field( 'camp_city', $post_id ) ?: carbon_get_post_meta( $post_id, 'camp_city' ) ?: carbon_get_theme_option( 'site_city' ) ?: 'в городе';
|
||
$opt_city = get_option( 'branch_city' ) ?: carbon_get_theme_option( 'site_city' ) ?: 'городе';
|
||
$opt_region = get_option( 'branch_region' ) ?: carbon_get_theme_option( 'site_region' ) ?: 'Московская область';
|
||
$opt_address = get_option( 'branch_address' ) ?: carbon_get_theme_option( 'site_address' ) ?: carbon_get_post_meta( $post_id, 'contact_address' ) ?: '';
|
||
$opt_coords = get_option( 'branch_coords' ) ?: carbon_get_post_meta( $post_id, 'contact_location' ) ?: '';
|
||
$opt_postal = get_option( 'branch_postal_code' ) ?: carbon_get_post_meta( $post_id, 'camp_postal_code' ) ?: carbon_get_theme_option( 'camp_postal_code' ) ?: '';
|
||
$opt_phone = get_option( 'branch_phone' ) ?: carbon_get_theme_option( 'site_phone' ) ?: carbon_get_post_meta( $post_id, 'contact_tel' ) ?: '';
|
||
$opt_email = get_option( 'branch_email' ) ?: carbon_get_theme_option( 'site_mail' ) ?: carbon_get_post_meta( $post_id, 'contact_mail' ) ?: '';
|
||
$opt_name = get_option( 'branch_name' ) ?: carbon_get_theme_option( 'site_name' ) ?: 'Декарт';
|
||
$opt_price_range = get_option( 'branch_price_range' ) ?: carbon_get_post_meta( $post_id, 'price_range' ) ?: carbon_get_theme_option( 'price_range' ) ?: '$$';
|
||
$opt_logo = get_option( 'branch_logo' ) ?: carbon_get_post_meta( $post_id, 'banner_img' );
|
||
$opt_social_raw = get_option( 'branch_social' ) ?: carbon_get_post_meta( $post_id, 'social_media' );
|
||
|
||
if ( ! get_option( 'branch_city_prep' ) && current_user_can( 'manage_options' ) ) {
|
||
add_action( 'wp_head', function() {
|
||
echo '<style>.camp-city-missing{outline:3px solid red;padding:4px}</style>';
|
||
}, 1 );
|
||
}
|
||
|
||
// ─── Универсальные переменные города ───
|
||
$city = $opt_city_prep;
|
||
$city_clean = $opt_city;
|
||
$city_with_prep = $opt_city_prep;
|
||
|
||
// ─── JSON-LD: ГЕО ───
|
||
$jsonld_city = $city_clean;
|
||
$jsonld_region = $opt_region;
|
||
$jsonld_addr = $opt_address ?: $jsonld_region . ', ' . $city_clean;
|
||
$jsonld_coords = $opt_coords;
|
||
$jsonld_coord_arr = $jsonld_coords ? array_map( 'trim', explode( ',', $jsonld_coords ) ) : array();
|
||
$jsonld_postal_code = $opt_postal;
|
||
|
||
// ─── JSON-LD: КОНТАКТЫ ───
|
||
$jsonld_phone = $opt_phone;
|
||
$jsonld_mail = $opt_email;
|
||
|
||
// ─── JSON-LD: ОРГАНИЗАЦИЯ ───
|
||
$jsonld_name = $opt_name;
|
||
$jsonld_price_range = $opt_price_range;
|
||
|
||
// ─── JSON-LD: ЛОГОТИП (ACF option → WP Customizer fallback) ───
|
||
if ( $opt_logo && is_array( $opt_logo ) ) {
|
||
$jsonld_img_url = $opt_logo['url'] ?? '';
|
||
} elseif ( $opt_logo ) {
|
||
$jsonld_img_url = wp_get_attachment_url( $opt_logo );
|
||
} else {
|
||
$jsonld_img_url = '';
|
||
}
|
||
if ( ! $jsonld_img_url ) {
|
||
$logo_id = get_theme_mod( 'custom_logo' );
|
||
$jsonld_img_url = $logo_id ? wp_get_attachment_url( $logo_id ) : '';
|
||
}
|
||
|
||
// ─── JSON-LD: СОЦСЕТИ ───
|
||
$jsonld_social = array();
|
||
if ( is_array( $opt_social_raw ) ) {
|
||
foreach ( $opt_social_raw as $s ) {
|
||
if ( ! empty( $s['url'] ) ) {
|
||
$jsonld_social[] = $s['url'];
|
||
}
|
||
}
|
||
}
|
||
|
||
// ─── Поля контента страницы (остаются per-page) ───
|
||
$priceMin = (int) carbon_get_post_meta( $post_id, 'price_half_day' );
|
||
|
||
?>
|
||
<main class="camp container_camp">
|
||
|
||
<?php
|
||
|
||
|
||
$hero = [
|
||
'h1' => carbon_get_post_meta( $post_id, 'hero_title_h1' ) ?: 'Детский лагерь Декарт.',
|
||
'span' => carbon_get_post_meta( $post_id, 'hero_title_span' ) ?: 'Яркое лето без забот!',
|
||
'btn_text' => carbon_get_post_meta( $post_id, 'hero_btn_primary' ) ?: 'Записаться на пробный день',
|
||
'image_id' => carbon_get_post_meta( $post_id, 'banner_img' ),
|
||
];
|
||
|
||
$metrics = [
|
||
[
|
||
'img_id' => carbon_get_post_meta( $post_id, 'hero_metric_1_img' ),
|
||
'number' => carbon_get_post_meta( $post_id, 'hero_metric_1_number' ) ?: '12',
|
||
'label' => carbon_get_post_meta( $post_id, 'hero_metric_1_label' ) ?: 'лет в городе',
|
||
'default_icon' => $theme_uri . '/assets/images/doodles/icon-home.png',
|
||
],
|
||
[
|
||
'img_id' => carbon_get_post_meta( $post_id, 'hero_metric_2_img' ),
|
||
'number' => carbon_get_post_meta( $post_id, 'hero_metric_2_number' ) ?: '2 500+',
|
||
'label' => carbon_get_post_meta( $post_id, 'hero_metric_2_label' ) ?: 'счастливых детей',
|
||
'default_icon' => $theme_uri . '/assets/images/doodles/icon-bulb.png',
|
||
],
|
||
[
|
||
'img_id' => carbon_get_post_meta( $post_id, 'hero_metric_3_img' ),
|
||
'number' => carbon_get_post_meta( $post_id, 'hero_metric_3_number' ) ?: '4.9 / 5',
|
||
'label' => carbon_get_post_meta( $post_id, 'hero_metric_3_label' ) ?: 'рейтинг от родителей',
|
||
'default_icon' => $theme_uri . '/assets/images/doodles/icon-award.png',
|
||
],
|
||
];
|
||
|
||
|
||
?>
|
||
<section class="section-bg hero-media-search" data-bg="hero" id="camp-hero">
|
||
<div class="container">
|
||
<div class="hero-media-search__container">
|
||
|
||
<!-- Левая колонка -->
|
||
<div class="hero-media-search__content">
|
||
<h1 class="heading-1"><?php echo wp_kses_post( $hero['h1'] ); ?></h1>
|
||
<h2 id="camp-hero-subtitle" class="hero-subtitle-brand"><?php echo wp_kses_post( $hero['span'] ); ?></h2>
|
||
|
||
<!-- Метрики (десктоп) -->
|
||
<div class="hero-media-search__propositions on-desktop">
|
||
<?php foreach ( $metrics as $metric ) : ?>
|
||
<?php render_hero_metric( $metric ); ?>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
|
||
<!-- CTA (десктоп) -->
|
||
<div class="hero-cta on-desktop">
|
||
<a href="#0" class="btn-write-camp about-us__cta-link" aria-label="<?php echo esc_attr( $hero['btn_text'] ); ?>">
|
||
<?php echo esc_html( $hero['btn_text'] ); ?> →
|
||
</a>
|
||
<p class="hero-cta__note">Один пробный день — за наш счёт. Оцените качество сами, а решение примете после.</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Правая колонка -->
|
||
<div class="hero-media-search__media">
|
||
<div class="hero-media-search__frame">
|
||
<?php if ( $hero['image_id'] ) : ?>
|
||
<?php echo wp_get_attachment_image( $hero['image_id'], 'full', false, [
|
||
'class' => 'hero-media-search__image',
|
||
'fetchpriority' => 'high',
|
||
'loading' => 'eager',
|
||
'alt' => esc_attr( wp_trim_words( $hero['h1'], 10 ) )
|
||
] ); ?>
|
||
<?php else : ?>
|
||
<img class="hero-media-search__image"
|
||
fetchpriority="high" src="<?php echo $theme_uri; ?>/assets/images/camp-hero.jpg"
|
||
alt="Детский лагерь Декарт <?php echo $city_with_prep; ?>" loading="eager">
|
||
<?php endif; ?>
|
||
|
||
<!-- Декоративные элементы -->
|
||
<img src="<?php echo $theme_uri; ?>/assets/images/doodles/hero-doodle-gears.svg"
|
||
alt="" class="doodle doodle--top-left" width="209" height="218">
|
||
<img src="<?php echo $theme_uri; ?>/assets/images/doodles/hero-doodle-pencils.svg"
|
||
alt="" class="doodle doodle--bottom-right" width="195" height="197">
|
||
</div>
|
||
|
||
<!-- Метрики -->
|
||
<div class="hero-media-search__wrapper">
|
||
<div class="hero-media-search__propositions on-mobile">
|
||
<?php foreach ( $metrics as $metric ) : ?>
|
||
<?php render_hero_metric( $metric ); ?>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
|
||
<div class="hero-cta on-mobile">
|
||
<a href="#0" class="btn-write-camp about-us__cta-link" aria-label="<?php echo esc_attr( $hero['btn_text'] ); ?>">
|
||
<?php echo esc_html( $hero['btn_text'] ); ?> →
|
||
</a>
|
||
<p class="hero-cta__note">Один пробный день — за наш счёт. Оцените качество сами, а решение примете после.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</section>
|
||
<section class="section-bg about-us" data-bg="white" id="camp-about">
|
||
<div class="container">
|
||
<div class="about-us__wrapper">
|
||
<div class="about-us__image-col">
|
||
<div class="about-us__frame">
|
||
<?php
|
||
$about_img_id = carbon_get_post_meta( $post_id, 'about_us_img' );
|
||
if ( $about_img_id ) :
|
||
echo wp_get_attachment_image( $about_img_id, 'large', false, [
|
||
'class' => 'about-us__image',
|
||
'loading' => 'lazy',
|
||
'alt' => 'Фото детского лагеря Декарт ' . $city_with_prep
|
||
] );
|
||
else :
|
||
echo '<div class="about-us__image-placeholder">
|
||
<svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
||
<rect x="3" y="3" width="18" height="18" rx="2"></rect>
|
||
<circle cx="8.5" cy="8.5" r="1.5"></circle>
|
||
<path d="M21 15l-5-5L5 21"></path>
|
||
</svg>
|
||
<span>Добавьте фото</span>
|
||
</div>';
|
||
endif;
|
||
?>
|
||
<img src="<?php echo $theme_uri; ?>/assets/images/doodles/galileo/paperplane-galileo.svg"
|
||
alt="" class="about-us__doodle about-us__doodle--plane" width="263" height="179">
|
||
<img src="<?php echo $theme_uri; ?>/assets/images/doodles/galileo/orangegear-white.svg"
|
||
alt="" class="about-us__doodle about-us__doodle--heart" width="35" height="35">
|
||
</div>
|
||
</div>
|
||
<div class="about-us__content-col">
|
||
<h2 class="camp_title about-us__title">Лето, которое не хочется ставить на паузу</h2>
|
||
<div class="about-us__text">
|
||
<?php echo wp_kses_post( carbon_get_post_meta( $post_id, 'about_us_text' ) ?: 'Всю зиму ребёнок в телефоне? Бабушка устала? А ведь лето может быть другим — ярким, живым, полезным.
|
||
В Dekart дети не просто под присмотром. Они собирают роботов, ставят опыты, играют в театре, бегают на квестах и находят друзей.А главное — бегут в лагерь каждое утро без уговоров.' ); ?>
|
||
</div>
|
||
<div class="about-us__social-proof">
|
||
<span class="about-us__badge">⭐ 2500+ мам доверили нам лето</span>
|
||
</div>
|
||
<div class="about-us__cta">
|
||
<a href="#" class="btn-write-camp about-us__cta-link">Хочу на пробный день →</a>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="section-bg suggestions" data-bg="mint" id="camp-advantages">
|
||
<div class="container">
|
||
<div class="suggestions__header">
|
||
<h2 class="camp_title">Почему мамы выбирают "Декарт": дети бегут сюда сами</h2>
|
||
<p class="suggestions__subtitle">Никаких уговоров по утрам. Никаких «забери меня». Только горящие глаза и «а можно ещё?»</p>
|
||
</div>
|
||
<div class="suggestions-wrapper"> <?php $suggestions = carbon_get_post_meta($post_id, 'suggestions' ); $icons = ['innovation-white.svg', 'steamprojects-35x35-1.svg', 'handson-35x35-1.svg', 'orangegear-white.svg', 'outdoor-white.svg', 'heart_sticker.svg'];
|
||
if (is_array($suggestions)) {
|
||
foreach ($suggestions as $index => $item) {
|
||
$suggestions_title = $item['suggestions_title'];
|
||
$suggestions_text = $item['suggestions_text'];
|
||
$icon_file = $icons[$index % count($icons)];
|
||
?> <div class="suggestions__item">
|
||
<div class="suggestions__icon-wrap">
|
||
<img src="<?php echo $theme_uri; ?>/assets/images/doodles/galileo/<?php echo $icon_file; ?>"
|
||
alt="<?php echo esc_attr( $suggestions_title ); ?>" class="suggestions__icon" loading="lazy">
|
||
</div>
|
||
<h3 class="suggestions__item_title"><?php echo esc_html( $suggestions_title ); ?></h3>
|
||
<p class="suggestions__item_text"><?php echo esc_html( $suggestions_text ); ?></p>
|
||
</div> <?php }
|
||
} ?> </div>
|
||
</div>
|
||
</section>
|
||
<style>
|
||
@media (max-width: 768px) {
|
||
.infograph__card::before {
|
||
display: none;
|
||
}
|
||
}
|
||
</style>
|
||
<section class="section-bg infograph" data-bg="white" id="camp-infograph">
|
||
<div class="container">
|
||
<div class="infograph__header">
|
||
<h2 class="camp_title">Цифры, которые говорят сами за себя</h2>
|
||
<p class="infograph__lead">Мы создаём среду, где каждый ребёнок раскрывает свой потенциал</p>
|
||
</div>
|
||
<div class="infograph__grid">
|
||
|
||
<div class="infograph__card">
|
||
<div class="infograph__card-icon">
|
||
<img loading="lazy" src="<?php echo $theme_uri; ?>/assets/images/age.svg" alt="Возраст детей — Образовательный центр Декарт <?php echo $city_with_prep; ?>" width="40" height="40">
|
||
</div>
|
||
<div class="infograph__card-body">
|
||
<p class="infograph__stat">6,5−11 лет</p>
|
||
<p class="infograph__label">возраст</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="infograph__card">
|
||
<div class="infograph__card-icon">
|
||
<img loading="lazy" src="<?php echo $theme_uri; ?>/assets/images/group.svg" alt="Группы до 10 детей — Образовательный центр Декарт <?php echo $city_with_prep; ?>" width="40" height="40">
|
||
</div>
|
||
<div class="infograph__card-body">
|
||
<p class="infograph__stat">до 10 детей</p>
|
||
<p class="infograph__label">каждая группа</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="infograph__card">
|
||
<div class="infograph__card-icon">
|
||
<img loading="lazy" src="<?php echo $theme_uri; ?>/assets/images/time.svg" alt="Время посещения на выбор — Образовательный центр Декарт <?php echo $city_with_prep; ?>" width="40" height="40">
|
||
</div>
|
||
<div class="infograph__card-body">
|
||
<p class="infograph__stat">на выбор</p>
|
||
<p class="infograph__label">время посещения</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="infograph__card">
|
||
<div class="infograph__card-icon">
|
||
<img loading="lazy" src="<?php echo $theme_uri; ?>/assets/images/price.svg" alt="Стоимость недели — Образовательный центр Декарт <?php echo $city_with_prep; ?>" width="40" height="40">
|
||
</div>
|
||
<div class="infograph__card-body">
|
||
<p class="infograph__stat">от <?php echo esc_html( number_format($priceMin, 0, ',', ' ') ); ?> ₽</p>
|
||
<p class="infograph__label">стоимость недели</p>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="section-bg programs" data-bg="mint" id="camp-programs">
|
||
<div class="container">
|
||
<h2 class="camp_title">Летние программы</h2>
|
||
<div class="programs__scroll-x">
|
||
<div class="programs__grid">
|
||
<?php
|
||
$programs = carbon_get_post_meta($post_id, 'programs');
|
||
if (is_array($programs)) {
|
||
foreach ($programs as $item) {
|
||
$programs_img = $item['programs_img'];
|
||
$programs_title = $item['programs_title'];
|
||
$programs_date = $item['programs_date'];
|
||
$programs_text = $item['programs_text'];
|
||
$programs_days = $item['programs_days'];
|
||
$programs_content = $item['programs_content'];
|
||
$programs_price_global = carbon_get_post_meta($post_id, 'price_half_day');?>
|
||
<article class="programs__card">
|
||
<img class="programs__image" loading="lazy" width="360" height="225" src="<?php echo $programs_img ? wp_get_attachment_url($programs_img) : $theme_uri . '/assets/images/placeholder.svg'; ?>" alt="<?php echo $programs_img && get_post_meta($programs_img, '_wp_attachment_image_alt', true) ? esc_attr(get_post_meta($programs_img, '_wp_attachment_image_alt', true)) : esc_attr($programs_title) . ' — Образовательный центр Декарт в ' . $city_clean; ?>">
|
||
<div class="programs__body">
|
||
<h3 class="programs__name"><?php echo esc_html($programs_title); ?></h3>
|
||
<p class="programs__date"><?php echo esc_html($programs_date); ?></p>
|
||
<p class="programs__desc"><?php echo esc_html($programs_text); ?></p>
|
||
<div class="programs__footer">
|
||
<span class="programs__price">От <?php echo number_format((int)$programs_price_global, 0, ',', ' '); ?> ₽</span>
|
||
<span class="programs__duration">за <?php echo esc_html($programs_days); ?></span>
|
||
</div>
|
||
<?php
|
||
// Понижаем H3→H4, удаляем пустые заголовки (защита от редактора)
|
||
$programs_fixed = preg_replace('/<h3\b([^>]*)>/i', '<h4$1>', $programs_content);
|
||
$programs_fixed = preg_replace('/<\/h3>/i', '</h4>', $programs_fixed);
|
||
$programs_fixed = preg_replace('/<h4[^>]*>\s*<\/h4>/i', '', $programs_fixed);
|
||
?><div class="programs_content hidden"><?php echo wp_kses_post($programs_fixed); ?></div>
|
||
<button class="programs__btn btn-program" aria-label="Подробнее о программе <?php echo esc_attr($programs_title); ?>">Подробнее</button>
|
||
</div>
|
||
</article>
|
||
<?php
|
||
}
|
||
} ?>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="section-bg bring-child" data-bg="white" id="camp-pricing">
|
||
<?php
|
||
$price_half_day = carbon_get_post_meta($post_id, 'price_half_day' );
|
||
$price_full_day = carbon_get_post_meta($post_id, 'price_full_day' );
|
||
?>
|
||
<h2 class="camp_title">Приводите ребёнка, когда вам удобно</h2>
|
||
<div class="bring-child-wrapper">
|
||
|
||
<div class="pricing-card pricing-card--half">
|
||
<div class="pricing-card__header">
|
||
<div class="pricing-card__badge pricing-card__badge--half">
|
||
<img loading="lazy" src="<?php echo $theme_uri; ?>/assets/images/green-star.svg" width="24" height="24" alt="">
|
||
</div>
|
||
<h3 class="pricing-card__title">Половина дня</h3>
|
||
<p class="pricing-card__desc">Время пребывания — на выбор (до обеда или до вечера)</p>
|
||
</div>
|
||
<div class="pricing-card__price">
|
||
<span class="pricing-card__amount"><?php echo number_format($price_half_day, 0, ',', ' '); ?> ₽</span>
|
||
<span class="pricing-card__period">за 5 дней</span>
|
||
</div>
|
||
<div class="pricing-card__slots">
|
||
<div class="pricing-card__slot">
|
||
<span class="pricing-card__slot-time">с 8:30 до 13:30</span>
|
||
<span class="pricing-card__slot-label">утренняя смена</span>
|
||
</div>
|
||
<div class="pricing-card__slot">
|
||
<span class="pricing-card__slot-time">с 13:30 до 18:30</span>
|
||
<span class="pricing-card__slot-label">вечерняя смена</span>
|
||
</div>
|
||
</div>
|
||
<ul class="pricing-card__features">
|
||
<li><b>5 дней</b> пребывания в клубе</li>
|
||
<li>творческие занятия и мастер-классы <b>1 раз в день</b></li>
|
||
<li>умные прогулки <b>1 раз в день</b></li>
|
||
</ul>
|
||
<div class="pricing-card__extra">
|
||
<img loading="lazy" src="<?php echo $theme_uri; ?>/assets/images/calendar.png" width="20" height="20" alt="Календарь — Образовательный центр Декарт <?php echo $city_with_prep; ?>">
|
||
<span>Тематическая неделя на выбор</span>
|
||
</div>
|
||
<button class="pricing-card__btn btn-write-camp">Занять место</button>
|
||
</div>
|
||
|
||
<div class="pricing-card pricing-card--full">
|
||
<div class="pricing-card__header">
|
||
<div class="pricing-card__badge pricing-card__badge--full">
|
||
<img loading="lazy" src="<?php echo $theme_uri; ?>/assets/images/star-02.svg" width="24" height="24" alt="">
|
||
</div>
|
||
<h3 class="pricing-card__title">Полный день</h3>
|
||
<p class="pricing-card__desc">Пребывание в клубе с утра до вечера, дополнительные активности</p>
|
||
</div>
|
||
<div class="pricing-card__price">
|
||
<span class="pricing-card__amount"><?php echo number_format($price_full_day, 0, ',', ' '); ?> ₽</span>
|
||
<span class="pricing-card__period">за 5 дней</span>
|
||
</div>
|
||
<div class="pricing-card__slots">
|
||
<div class="pricing-card__slot">
|
||
<span class="pricing-card__slot-time">с 8:30 до 18:30</span>
|
||
<span class="pricing-card__slot-label">полный день</span>
|
||
</div>
|
||
</div>
|
||
<ul class="pricing-card__features">
|
||
<li><b>5 дней</b> пребывания в клубе</li>
|
||
<li>творческие занятия и мастер-классы <b>2 раза в день</b></li>
|
||
<li>умные прогулки <b>2 раза в день</b></li>
|
||
<li>тематические экскурсии каждую неделю</li>
|
||
</ul>
|
||
<div class="pricing-card__extra">
|
||
<img loading="lazy" src="<?php echo $theme_uri; ?>/assets/images/calendar+.png" width="20" height="20" alt="Календарь — Образовательный центр Декарт <?php echo $city_with_prep; ?>">
|
||
<span>Тематическая неделя на выбор</span>
|
||
</div>
|
||
<button class="pricing-card__btn btn-write-camp">Занять место</button>
|
||
</div>
|
||
|
||
</div>
|
||
</section>
|
||
|
||
<section class="section-bg mentors" data-bg="mint" id="camp-mentors">
|
||
<h2 class="camp_title">Наши наставники и ведущие мастер-классов</h2>
|
||
<div class="mentors__scroll-x">
|
||
<div class="mentors-wrapper">
|
||
<?php
|
||
$mentors = carbon_get_post_meta($post_id, 'mentors' );
|
||
if (is_array($mentors)) {
|
||
foreach ($mentors as $item) {
|
||
$mentorName = $item['mentor_name'] ?? '';
|
||
$mentor_job = $item['mentor_job'] ?? '';
|
||
$mentor_foto = $item['mentor_foto'] ?? 0;
|
||
$mentor_about = $item['mentor_about'] ?? '';
|
||
?>
|
||
<div class="mentors__item">
|
||
<div class="mentors__card">
|
||
<div class="mentors__card-top">
|
||
<?php if ( !$mentor_foto ) { ?>
|
||
<img class="mentors__photo" loading="lazy" width="120" height="120" src="<?php echo $theme_uri; ?>/assets/images/no-photo.png" alt="<?php echo esc_attr( $mentorName ); ?> — Образовательный центр Декарт <?php echo $city_with_prep; ?>">
|
||
<?php } else { ?>
|
||
<img class="mentors__photo" loading="lazy" width="120" height="120" src="<?php echo wp_get_attachment_url($mentor_foto); ?>" alt="<?php echo esc_attr( $mentorName ); ?> — Образовательный центр Декарт <?php echo $city_with_prep; ?>">
|
||
<?php } ?>
|
||
</div>
|
||
<div class="mentors__card-body">
|
||
<h3 class="mentors__name"><?php echo esc_html($mentorName); ?></h3>
|
||
<p class="mentors__job"><?php echo esc_html($mentor_job); ?></p>
|
||
<?php if ($mentor_about) : ?>
|
||
<p class="mentors__about"><?php echo esc_html($mentor_about); ?></p>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<?php }
|
||
} ?>
|
||
</div>
|
||
</div>
|
||
|
||
</section>
|
||
|
||
<section class="section-bg routine" data-bg="white" id="camp-schedule">
|
||
<h2 class="camp_title">Распорядок дня в клубе</h2>
|
||
<div class="routine-wrapper">
|
||
<?php
|
||
$routine = carbon_get_post_meta($post_id, 'routine' );
|
||
if (is_array($routine)) {
|
||
foreach ($routine as $item) {
|
||
$routine_time = $item['routine_time'];
|
||
$routine_title = $item['routine_title'];
|
||
$routine_text = $item['routine_text'];
|
||
?>
|
||
<div class="routine__item">
|
||
<div class="routine__item_time"><?php echo esc_html($routine_time); ?></div>
|
||
<div class="routine__item_circle"></div>
|
||
<div class="routine__item_text">
|
||
<p class="routine__item_time-mobile"><?php echo esc_html($routine_time); ?></p>
|
||
<h3 class="routine__item_text-title"><?php echo esc_html($routine_title); ?></h3>
|
||
<p class="routine__item_text-text"><?php echo esc_html($routine_text); ?></p>
|
||
</div>
|
||
</div>
|
||
<?php }
|
||
} ?>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="section-bg foto" data-bg="mint" id="camp-gallery">
|
||
<h2 class="camp_title">Наши фотографии</h2>
|
||
<?php
|
||
$fotos = carbon_get_post_meta($post_id, 'fotos' );
|
||
if (is_array($fotos) && !empty($fotos)) :
|
||
?>
|
||
<div class="lw-gallery">
|
||
<div class="lw-gallery__grid">
|
||
<?php foreach ($fotos as $item) :
|
||
$img_id = $item['foto'];
|
||
$img_url = wp_get_attachment_url($img_id);
|
||
$full_url = wp_get_attachment_image_url($img_id, 'full');
|
||
$alt = esc_attr(get_post_meta($img_id, '_wp_attachment_image_alt', true));
|
||
if ( ! $alt ) $alt = 'Фото лагеря — Образовательный центр Декарт ' . $city_with_prep;
|
||
?>
|
||
<div class="lw-gallery__item">
|
||
<img class="lw-gallery__thumb"
|
||
src="<?php echo esc_url($img_url); ?>"
|
||
alt="<?php echo $alt; ?>"
|
||
loading="lazy"
|
||
width="400" height="300"
|
||
data-full="<?php echo esc_url($full_url); ?>">
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</div>
|
||
<div class="lw-modal" id="lw-modal-gallery" role="dialog" aria-modal="true" aria-labelledby="lw-modal-title" aria-hidden="true">
|
||
<div class="lw-modal__overlay"></div>
|
||
<div class="lw-modal__content">
|
||
<h3 id="lw-modal-title" class="screen-reader-text">Просмотр фото</h3>
|
||
<button class="lw-modal__close" aria-label="Закрыть">
|
||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none"><path d="M18 6L6 18M6 6l12 12" stroke="#fff" stroke-width="2" stroke-linecap="round"></path></svg>
|
||
</button>
|
||
<img class="lw-modal__img" src="<?php echo esc_url( $theme_uri ); ?>/assets/images/placeholder.svg" alt="Форма записи">
|
||
</div>
|
||
</div>
|
||
<?php endif; ?>
|
||
</section>
|
||
|
||
<section class="section-bg camp-reviews reviews-cards" data-bg="white" id="camp-reviews">
|
||
<h2 class="camp_title">Что говорят о нас родители</h2>
|
||
<?php
|
||
$review_items = carbon_get_post_meta($post_id, 'camp_reviews_list');
|
||
$total_count = is_array($review_items) ? count($review_items) : 0;
|
||
if ($total_count > 0) :
|
||
$items = array_values($review_items);
|
||
$card_idx = 0;
|
||
?>
|
||
<div class="reviews-cards">
|
||
<div class="lw-scroll-x">
|
||
<div class="lw-grid lw-grid--3">
|
||
<?php foreach ($items as $item) :
|
||
$card_idx++;
|
||
$author = $item['review_author'] ?? '';
|
||
$text = $item['review_text'] ?? '';
|
||
$raw_rating = $item['review_rating'] ?? '';
|
||
$avatar_id = !empty($item['review_avatar']) ? (int)$item['review_avatar'] : 0;
|
||
$teacher = $item['review_teacher'] ?? array();
|
||
$date = $item['review_date'] ?? '';
|
||
$stars = max(1, min(5, (int)$raw_rating));
|
||
$name = $author ?: 'Анонимно';
|
||
$is_long = strlen( wp_strip_all_tags( $text ) ) > 350;
|
||
$batch = (int) ceil( $card_idx / 12 );
|
||
if (empty($text)) continue;
|
||
?>
|
||
<article class="lw-card reveal" data-batch="<?php echo (int) $batch; ?>">
|
||
<div class="lw-flex lw-flex--row lw-gap-12 lw-items-start">
|
||
<div class="lw-avatar lw-avatar--48">
|
||
<?php if ($avatar_id && wp_attachment_is_image($avatar_id)) : ?>
|
||
<?php echo wp_get_attachment_image($avatar_id, [48, 48], false, ['class' => 'lw-avatar__img', 'loading' => 'lazy', 'alt' => esc_attr($name)]); ?>
|
||
<?php else : ?>
|
||
<div class="lw-avatar lw-avatar--48 lw-avatar--letter">
|
||
<span class="lw-avatar__letter"><?php echo esc_html( $name ? mb_strtoupper( mb_substr( $name, 0, 1 ) ) : '?' ); ?></span>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
<div class="lw-flex lw-flex--col" style="flex:1; min-width:0;">
|
||
<div class="lw-text-dark lw-font-semibold"><?php echo esc_html($name); ?></div>
|
||
<?php if ( ! empty( $teacher[0]['id'] ) ) : ?>
|
||
<div class="lw-text-xs lw-text-gray">
|
||
Преподаватель: <a href="<?php echo esc_url( get_permalink( $teacher[0]['id'] ) ); ?>" class="review-card__teacher-link"><?php echo esc_html( get_the_title( $teacher[0]['id'] ) ); ?></a>
|
||
</div>
|
||
<?php endif; ?>
|
||
<div class="lw-badge lw-badge--verified">✓ Проверенный отзыв</div>
|
||
</div>
|
||
</div>
|
||
<div class="lw-stars lw-mt-8">
|
||
<?php for ($i = 1; $i <= 5; $i++) : ?>
|
||
<svg class="lw-star <?php echo $i <= $stars ? 'lw-star--filled' : ''; ?>" width="16" height="16" viewBox="0 0 21 19" fill="none">
|
||
<path d="M9.58463 1.50884C9.89101 0.602477 11.1729 0.602476 11.4793 1.50884L13.1158 6.35007C13.2531 6.75637 13.6343 7.02985 14.0631 7.02985H19.2721C20.2504 7.02985 20.6467 8.28958 19.8447 8.84971L15.6995 11.7446C15.335 11.9991 15.1822 12.4636 15.3247 12.8847L16.9239 17.6158C17.233 18.5302 16.1954 19.3085 15.404 18.7559L11.1045 15.7533C10.7606 15.5131 10.3033 15.5131 9.95941 15.7533L5.65991 18.7559C4.86857 19.3085 3.83092 18.5302 4.14001 17.6158L5.73926 12.8847C5.8816 12.4636 5.72891 11.9991 5.36448 11.7446L1.21924 8.84971C0.417196 8.28958 0.813532 7.02985 1.79181 7.02985H7.00081C7.42969 7.02985 7.81081 6.75637 7.94815 6.35007L9.58463 1.50884Z" fill="currentColor"></path>
|
||
</svg>
|
||
<?php endfor; ?>
|
||
</div>
|
||
<div class="lw-card__text lw-mt-8<?php echo $is_long ? ' review-card__text--clamped' : ''; ?>">
|
||
<?php echo wp_kses_post($text); ?>
|
||
</div>
|
||
<div class="review-card__footer">
|
||
<?php if ($is_long) : ?>
|
||
<button class="review-card__btn-more" aria-label="Читать ещё">Читать ещё</button>
|
||
<?php endif; ?>
|
||
<?php if ($date) : ?>
|
||
<span class="review-card__date"><?php echo esc_html($date); ?></span>
|
||
<?php endif; ?>
|
||
</div>
|
||
</article>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<?php if ( $total_count > 12 ) : ?>
|
||
<div class="reviews-loadmore" id="reviews-loadmore">
|
||
<button type="button" class="reviews-loadmore__btn">Показать ещё</button>
|
||
</div>
|
||
<?php endif; ?>
|
||
<?php endif; ?>
|
||
</section>
|
||
|
||
|
||
|
||
<section class="section-bg faq-section" id="camp-faq">
|
||
<div class="container">
|
||
<h2 class="faq-section__title">Часто задаваемые вопросы</h2>
|
||
<div class="faq-section__wrapper">
|
||
|
||
<?php
|
||
$questions = carbon_get_post_meta($post_id, 'questions' );
|
||
$HTMcol1 = '';
|
||
$HTMcol2 = '';
|
||
|
||
$count = 0;
|
||
if (is_array($questions)) {
|
||
foreach ($questions as $item) {
|
||
$questions_question = $item['questions_question'];
|
||
$questions_answer = $item['questions_answer'];
|
||
$accordion_item = "<div class='box__accordion'>
|
||
<div class='box__accordion_label' role='button' tabindex='0'>
|
||
<span>" . esc_html($questions_question) . "</span>
|
||
<svg role='presentation' focusable='false' width='36px' height='36px' viewBox='0 0 24 24'>
|
||
<g stroke='none' stroke-width='2px' fill='none' fill-rule='evenodd' stroke-linecap='square'>
|
||
<g transform='translate(1.000000, 1.000000)' stroke='currentColor'>
|
||
<path d='M0,11 L22,11'></path>
|
||
<path d='M11,0 L11,22'></path>
|
||
</g>
|
||
</g>
|
||
</svg>
|
||
</div>
|
||
<div class='box__accordion_content'>
|
||
<div class='box__accordion_content-text'>" . wp_kses_post($questions_answer) . "</div>
|
||
</div>
|
||
</div>";
|
||
if ($count % 2 === 0) {
|
||
$HTMcol1 .= $accordion_item;
|
||
} else {
|
||
$HTMcol2 .= $accordion_item;
|
||
}
|
||
$count++;
|
||
}
|
||
}
|
||
echo "<div class='faq-section__col'>$HTMcol1</div>";
|
||
echo "<div class='faq-section__col'>$HTMcol2</div>";
|
||
?>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="section-bg camp-contact" data-bg="white" id="camp-contacts">
|
||
<?php
|
||
$contact_tel = $opt_phone;
|
||
$contact_address = $opt_address;
|
||
$contact_location = $opt_coords;
|
||
$contact_location_text = carbon_get_post_meta($post_id, 'contact_location_text' );
|
||
$contact_mail = $opt_email;
|
||
?>
|
||
<h2 class="camp_title">Контакты</h2>
|
||
<div class="contact-wrapper">
|
||
<div class="contact-content">
|
||
<div class="contact_subtitle">Телефон:</div>
|
||
<a class="contact_tel" href="tel:+<?php echo preg_replace('/[^0-9]/', '', $contact_tel); ?>"><?php echo esc_html($contact_tel); ?></a>
|
||
<div class="contact_subtitle">Почта:</div>
|
||
<a class="contact_tel" href="mailto:<?php echo esc_attr($contact_mail); ?>"><?php echo esc_html($contact_mail); ?></a>
|
||
<div class="contact_subtitle">Адрес:</div>
|
||
<div class="contact_tel"><?php echo esc_html($contact_address); ?></div>
|
||
<div class="contact_subtitle">Наши соцсети:</div>
|
||
<div class="contact_social">
|
||
<?php
|
||
if ( is_array( $opt_social_raw ) ) {
|
||
foreach( $opt_social_raw as $item ) {
|
||
$link = $item['url'] ?? '';
|
||
$name = $item['name'] ?? '';
|
||
if ( $link ) { ?>
|
||
<a class="social_item" href="<?php echo esc_url($link); ?>" target="_blank" rel="noopener noreferrer" title="<?php echo esc_attr($name); ?>">
|
||
<span class="social_item_label"><?php echo esc_html($name ?: $link); ?></span>
|
||
</a>
|
||
<?php }
|
||
}
|
||
} ?>
|
||
</div>
|
||
</div>
|
||
<div class="contact-map">
|
||
<div id="ya-map" style="width: 100%; height: 625px;"></div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
</main>
|
||
|
||
<div class="modal-programs" role="dialog" aria-modal="true" aria-label="Программа лагеря">
|
||
<div class="modal-programs__card">
|
||
<button class="modal-programs__close btn-close-programs" aria-label="Закрыть">
|
||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none"><path d="M18 6L6 18M6 6l12 12" stroke="#fff" stroke-width="2" stroke-linecap="round"></path></svg>
|
||
</button>
|
||
<div class="modal-programs__img">
|
||
<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='300'%3E%3C/svg%3E" alt="">
|
||
</div>
|
||
<div class="modal-programs__body">
|
||
<?php if (!empty($programs_title)) : ?><h3 class="programs__item_title"><?php echo esc_html($programs_title); ?></h3><?php else : ?><p class="program-subtitle">Тема уточняется</p><?php endif; ?>
|
||
<p class="programs__item_price"></p>
|
||
<div class="programs__content"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="modal-mentors" role="dialog" aria-modal="true" aria-label="Информация о наставнике">
|
||
<div class="modal-mentors-wrapper">
|
||
<button class="btn-close-mentors" aria-label="Закрыть">
|
||
<svg role="presentation" class="t-popup__close-icon" width="23px" height="23px" viewBox="0 0 23 23">
|
||
<g stroke="none" stroke-width="1" fill="#3bb273" fill-rule="evenodd">
|
||
<rect
|
||
transform="translate(11.313708, 11.313708) rotate(-45.000000) translate(-11.313708, -11.313708) "
|
||
x="10.3137085" y="-3.6862915" width="2" height="30"></rect>
|
||
<rect
|
||
transform="translate(11.313708, 11.313708) rotate(-315.000000) translate(-11.313708, -11.313708) "
|
||
x="10.3137085" y="-3.6862915" width="2" height="30"></rect>
|
||
</g>
|
||
</svg>
|
||
</button>
|
||
<div class="modal-programs__img">
|
||
<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='300'%3E%3C/svg%3E" alt="">
|
||
</div>
|
||
<div class="modal-mentors__content">
|
||
<div class="modal-mentors_name"></div>
|
||
<div class="modal-mentors_job"></div>
|
||
<div class="modal-mentors__directions"></div>
|
||
<div class="modal-mentors__about">
|
||
<div class="about-item">
|
||
<img src="<?php echo $theme_uri; ?>/assets/images/icons/icon-education.svg" alt="" width="60" height="58" loading="lazy">
|
||
<div class="mentors__about-col">
|
||
<p class="mentors__about-col_title">Образование:</p>
|
||
<div class="mentors__about-col_text"></div>
|
||
</div>
|
||
</div>
|
||
<div class="about-item">
|
||
<img src="<?php echo $theme_uri; ?>/assets/images/icons/icon-experience.svg" alt="" width="59" height="58" loading="lazy">
|
||
<div class="mentors__about-col">
|
||
<p class="mentors__about-col_title">Опыт работы в сфере образования:</p>
|
||
<div class="mentors__experience-col_text"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="modal-additional__education">
|
||
<img src="<?php echo $theme_uri; ?>/assets/images/icons/icon-certificate.svg" alt="" width="58" height="60" loading="lazy">
|
||
<div class="mentors__about-col">
|
||
<p class="mentors__about-col_title">Дополнительное образование:</p>
|
||
<div class="modal-additional__education_list">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
(function() {
|
||
var mapLoaded = false;
|
||
var mapContainer = document.getElementById("ya-map");
|
||
if (!mapContainer) return;
|
||
|
||
var observer = new IntersectionObserver(function(entries) {
|
||
if (entries[0].isIntersecting && !mapLoaded) {
|
||
mapLoaded = true;
|
||
observer.disconnect();
|
||
|
||
var script = document.createElement("script");
|
||
script.src = "https://api-maps.yandex.ru/2.1/?lang=ru_RU";
|
||
script.onerror = function() { console.warn("Yandex Maps API failed to load"); };
|
||
script.onload = function() {
|
||
ymaps.ready(function() {
|
||
var coords = <?php echo $contact_location ? '[' . esc_js($contact_location) . ']' : '[55.76, 37.64]'; ?>;
|
||
var map = new ymaps.Map("ya-map", {
|
||
center: coords,
|
||
zoom: 16
|
||
}, {
|
||
searchControlProvider: "yandex#search"
|
||
});
|
||
|
||
var placemark = new ymaps.Placemark(
|
||
coords,
|
||
{ iconContent: "<?php echo esc_js($contact_location_text); ?>" },
|
||
{ preset: "islands#redStretchyIcon" }
|
||
);
|
||
map.geoObjects.add(placemark);
|
||
});
|
||
};
|
||
document.body.appendChild(script);
|
||
}
|
||
}, { rootMargin: "200px" });
|
||
|
||
observer.observe(mapContainer);
|
||
})();
|
||
</script>
|
||
|
||
|
||
<?php
|
||
// ─────────────────────────────────────────────────────────────
|
||
// JSON-LD: Event (смены) + FAQ + AggregateRating (отзывы)
|
||
// ─────────────────────────────────────────────────────────────
|
||
$programs = carbon_get_post_meta($post_id, 'programs');
|
||
$ld_events = array();
|
||
if ( is_array( $programs ) ) {
|
||
foreach ( $programs as $item ) {
|
||
if ( empty( $item['programs_title'] ) && empty( $item['programs_text'] ) ) {
|
||
continue;
|
||
}
|
||
$ev = array(
|
||
'@type' => 'Event',
|
||
'eventStatus' => 'https://schema.org/EventScheduled',
|
||
'organizer' => array( '@id' => home_url('/') . '#organization' ),
|
||
'location' => array( '@id' => get_permalink( $post_id ) ),
|
||
);
|
||
if ( ! empty( $item['programs_title'] ) ) {
|
||
$ev['name'] = wp_strip_all_tags( $item['programs_title'] );
|
||
}
|
||
if ( ! empty( $item['programs_text'] ) ) {
|
||
$ev['description'] = wp_strip_all_tags( $item['programs_text'] );
|
||
}
|
||
if ( ! empty( $item['programs_date'] ) ) {
|
||
$raw = wp_strip_all_tags( $item['programs_date'] );
|
||
// ISO: 2025-05-26
|
||
if ( preg_match( '/(\d{4})-(\d{2})-(\d{2})/', $raw, $m ) ) {
|
||
$ev['startDate'] = $m[1] . '-' . $m[2] . '-' . $m[3];
|
||
// DD.MM.YYYY
|
||
} elseif ( preg_match( '/(\d{2})\.(\d{2})\.(\d{4})/', $raw, $m ) ) {
|
||
$ev['startDate'] = $m[3] . '-' . $m[2] . '-' . $m[1];
|
||
// Русские месяцы: "26–30 мая 2025" или "30 июня–4 июля 2025"
|
||
} elseif ( preg_match( '/(\d{1,2})\s*(?:[–—\-]|\s*–\s*)\d{1,2}\s+([а-яё]+)/ui', $raw, $m )
|
||
|| preg_match( '/(\d{1,2})\s+([а-яё]+)\s*[–—\-]/ui', $raw, $m )
|
||
|| preg_match( '/(\d{1,2})\s+([а-яё]+)\s+\d{4}/ui', $raw, $m ) ) {
|
||
$ru_months = array(
|
||
'января' => '01', 'февраля' => '02', 'марта' => '03',
|
||
'апреля' => '04', 'мая' => '05', 'июня' => '06',
|
||
'июля' => '07', 'августа' => '08', 'сентября' => '09',
|
||
'октября' => '10', 'ноября' => '11', 'декабря' => '12',
|
||
);
|
||
$month_name = mb_strtolower( trim( $m[2] ) );
|
||
if ( isset( $ru_months[ $month_name ] ) ) {
|
||
preg_match( '/(\d{4})/u', $raw, $y );
|
||
$ev['startDate'] = ( $y[1] ?? date('Y') ) . '-' . $ru_months[ $month_name ] . '-' . str_pad( $m[1], 2, '0', STR_PAD_LEFT );
|
||
}
|
||
// Fallback: только год
|
||
} elseif ( preg_match( '/\d{4}/', $raw, $y ) ) {
|
||
$ev['startDate'] = $y[0] . '-06-01';
|
||
}
|
||
if ( isset( $ev['description'] ) && $ev['description'] ) {
|
||
$ev['description'] .= ' — ' . $raw;
|
||
} else {
|
||
$ev['description'] = $raw;
|
||
}
|
||
}
|
||
if ( ! empty( $item['programs_img'] ) ) {
|
||
$ev['image'] = wp_get_attachment_url( $item['programs_img'] );
|
||
}
|
||
$_half_price = (int)carbon_get_post_meta($post_id, 'price_half_day');
|
||
if ( $_half_price > 0 ) {
|
||
$ev['offers'] = array(
|
||
'@type' => 'Offer',
|
||
'price' => $_half_price,
|
||
'priceCurrency' => 'RUB',
|
||
);
|
||
}
|
||
if ( $jsonld_img_url && empty( $ev['image'] ) ) {
|
||
$ev['image'] = $jsonld_img_url;
|
||
}
|
||
$ld_events[] = $ev;
|
||
}
|
||
}
|
||
|
||
$ld_questions = carbon_get_post_meta( $post_id, 'questions' );
|
||
$ld_faq = array();
|
||
if ( is_array( $ld_questions ) ) {
|
||
$faq_main_entity = array();
|
||
foreach ( $ld_questions as $q ) {
|
||
$name = ! empty( $q['questions_question'] ) ? wp_strip_all_tags( $q['questions_question'] ) : '';
|
||
$answer = ! empty( $q['questions_answer'] ) ? wp_strip_all_tags( $q['questions_answer'] ) : '';
|
||
if ( $name && $answer ) {
|
||
$faq_main_entity[] = array(
|
||
'@type' => 'Question',
|
||
'name' => $name,
|
||
'acceptedAnswer' => array(
|
||
'@type' => 'Answer',
|
||
'text' => $answer,
|
||
),
|
||
);
|
||
}
|
||
}
|
||
if ( ! empty( $faq_main_entity ) ) {
|
||
$ld_faq[] = array(
|
||
'@type' => 'FAQPage',
|
||
'mainEntity' => $faq_main_entity,
|
||
);
|
||
}
|
||
}
|
||
|
||
$agg_rating = null;
|
||
$agg_reviews = new WP_Query( array(
|
||
'post_type' => 'reviews',
|
||
'posts_per_page' => -1,
|
||
'fields' => 'ids',
|
||
'suppress_filters' => true,
|
||
'meta_query' => array( array(
|
||
'key' => 'review_type',
|
||
'value' => 'camp',
|
||
'compare' => '=',
|
||
) ),
|
||
) );
|
||
if ( $agg_reviews->have_posts() ) {
|
||
$total_stars = 0;
|
||
$review_cnt = 0;
|
||
foreach ( $agg_reviews->posts as $rid ) {
|
||
$star = (int) carbon_get_post_meta( $rid, 'review_star' );
|
||
if ( $star > 0 ) {
|
||
$total_stars += $star;
|
||
$review_cnt++;
|
||
}
|
||
}
|
||
if ( $review_cnt > 0 ) {
|
||
$agg_rating = array(
|
||
'@type' => 'AggregateRating',
|
||
'itemReviewed' => array( '@id' => get_permalink( $post_id ) ),
|
||
'ratingValue' => round( $total_stars / $review_cnt, 1 ),
|
||
'reviewCount' => $review_cnt,
|
||
'bestRating' => 5,
|
||
'worstRating' => 1,
|
||
);
|
||
}
|
||
}
|
||
wp_reset_postdata();
|
||
|
||
$localbusiness = array(
|
||
'@type' => 'LocalBusiness',
|
||
'@id' => get_permalink( $post_id ),
|
||
'name' => 'Декарт ' . $city_clean,
|
||
'alternateName' => array( 'Decart', 'Образовательный центр Декарт' ),
|
||
'description' => 'Детский лагерь в ' . $city_clean . ' — образовательный центр Декарт. Летние программы, творчество, развитие.',
|
||
'url' => get_permalink( $post_id ),
|
||
);
|
||
if ( $jsonld_phone ) $localbusiness['telephone'] = $jsonld_phone;
|
||
if ( $jsonld_mail ) $localbusiness['email'] = $jsonld_mail;
|
||
if ( $jsonld_img_url ) $localbusiness['image'] = $jsonld_img_url;
|
||
|
||
$localbusiness['address'] = array(
|
||
'@type' => 'PostalAddress',
|
||
'addressLocality' => $jsonld_city,
|
||
'streetAddress' => $jsonld_addr,
|
||
'addressRegion' => $jsonld_region,
|
||
'addressCountry' => 'RU',
|
||
);
|
||
if ( $jsonld_postal_code ) {
|
||
$localbusiness['address']['postalCode'] = $jsonld_postal_code;
|
||
}
|
||
|
||
if ( ! empty( $jsonld_coord_arr[0] ) && ! empty( $jsonld_coord_arr[1] ) && is_numeric( $jsonld_coord_arr[0] ) && is_numeric( $jsonld_coord_arr[1] ) ) {
|
||
$localbusiness['geo'] = array(
|
||
'@type' => 'GeoCoordinates',
|
||
'latitude' => (float) $jsonld_coord_arr[0],
|
||
'longitude' => (float) $jsonld_coord_arr[1],
|
||
);
|
||
}
|
||
|
||
$localbusiness['areaServed'] = $city_clean . ', ' . $jsonld_region;
|
||
$localbusiness['openingHoursSpecification'] = array(
|
||
array(
|
||
'@type' => 'OpeningHoursSpecification',
|
||
'dayOfWeek' => array( 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday' ),
|
||
'opens' => '08:30',
|
||
'closes' => '18:30',
|
||
),
|
||
);
|
||
$localbusiness['priceRange'] = $jsonld_price_range;
|
||
$localbusiness['parentOrganization'] = array( '@id' => home_url('/') . '#organization' );
|
||
|
||
$organization = array(
|
||
'@type' => 'Organization',
|
||
'@id' => home_url('/') . '#organization',
|
||
'name' => $jsonld_name,
|
||
'url' => home_url('/'),
|
||
);
|
||
if ( $jsonld_img_url ) {
|
||
$organization['logo'] = $jsonld_img_url;
|
||
}
|
||
if ( ! empty( $jsonld_social ) ) {
|
||
$organization['sameAs'] = $jsonld_social;
|
||
}
|
||
$organization['foundingDate'] = '2020';
|
||
if ( $jsonld_phone || $jsonld_mail ) {
|
||
$cp = array( '@type' => 'ContactPoint' );
|
||
if ( $jsonld_phone ) $cp['telephone'] = $jsonld_phone;
|
||
if ( $jsonld_mail ) $cp['email'] = $jsonld_mail;
|
||
$cp['contactType'] = 'customer service';
|
||
$cp['areaServed'] = 'RU';
|
||
$cp['availableLanguage'] = array( 'Russian' );
|
||
$organization['contactPoint'] = array( $cp );
|
||
}
|
||
|
||
if ( $agg_rating ) {
|
||
$localbusiness['aggregateRating'] = $agg_rating;
|
||
}
|
||
$ld_website = array(
|
||
'@type' => 'WebSite',
|
||
'@id' => home_url('/') . '#website',
|
||
'url' => home_url('/'),
|
||
'name' => $jsonld_name,
|
||
'inLanguage' => 'ru-RU',
|
||
'publisher' => array( '@id' => home_url('/') . '#organization' ),
|
||
'potentialAction' => array(
|
||
'@type' => 'SearchAction',
|
||
'target' => array(
|
||
'@type' => 'EntryPoint',
|
||
'urlTemplate' => home_url('/') . '?s={search_term_string}',
|
||
),
|
||
'query-input' => 'required name=search_term_string',
|
||
),
|
||
);
|
||
$ld_webpage = array(
|
||
'@type' => 'WebPage',
|
||
'@id' => get_permalink( $post_id ),
|
||
'url' => get_permalink( $post_id ),
|
||
'inLanguage' => 'ru-RU',
|
||
'name' => wp_get_document_title() ?: 'Городской лагерь в ' . $city_clean,
|
||
'isPartOf' => array( '@id' => home_url('/') . '#website' ),
|
||
'about' => array( '@id' => get_permalink( $post_id ) ),
|
||
);
|
||
$ld_breadcrumb = array(
|
||
'@type' => 'BreadcrumbList',
|
||
'@id' => get_permalink( $post_id ) . '#breadcrumb',
|
||
'itemListElement' => array(
|
||
array(
|
||
'@type' => 'ListItem',
|
||
'position' => 1,
|
||
'name' => 'Главная',
|
||
'item' => home_url( '/' ),
|
||
),
|
||
array(
|
||
'@type' => 'ListItem',
|
||
'position' => 2,
|
||
'name' => 'Городской лагерь в ' . $city_clean,
|
||
'item' => get_permalink( $post_id ),
|
||
),
|
||
),
|
||
);
|
||
$ld_graph = array_merge( array( $ld_website, $ld_webpage, $ld_breadcrumb, $localbusiness, $organization ), $ld_events, $ld_faq );
|
||
|
||
if ( ! empty( $ld_graph ) ) {
|
||
$jsonld_data = array(
|
||
'@context' => 'https://schema.org',
|
||
'@graph' => $ld_graph,
|
||
);
|
||
echo '<script type="application/ld+json">' . wp_json_encode( $jsonld_data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_HEX_TAG ) . '</script>' . "\n";
|
||
}
|
||
?>
|
||
<?php
|
||
get_footer();
|