shkola/wp-content/themes/dekart/single-teacher.php
2026-09-13 22:10:59 +00:00

1079 lines
58 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
/**
* Личная страница преподавателя (Bento 2026).
*
* Данные — из CF карточки преподавателя. Общие части: reviews-link,
* teachers-cards, contacts, author-eaat. Sticky-CTA на мобильном.
*
* @package Dekart
*/
if (! defined('ABSPATH')) {
exit;
}
// og:image:alt из featured image (паттерн page-camp.php)
add_action('wp_head', function () {
if (! is_singular('teacher')) {
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);
get_header();
$tid = (int) get_the_ID();
$full_name = get_the_title($tid);
// ─── Гео / контакты филиала ───
$branch_phone = get_option('branch_phone') ?: carbon_get_theme_option('site_phone');
$branch_city = get_option('branch_city') ?: carbon_get_theme_option('site_city', 'Щёлково');
$branch_city_prep = get_option('branch_city_prep', 'в Щёлково') ?: 'в Щёлково';
$branch_name = get_option('branch_name') ?: carbon_get_theme_option('site_name', 'Декарт');
// Тел.: цифры и «+». WhatsApp: 8-XXXXXXXXXX → 7-XXXXXXXXXX, без номера — без ссылки.
$phone_clean = $branch_phone ? preg_replace('/[^0-9+]/', '', $branch_phone) : '';
$wa_on = (bool) get_option('branch_messenger_whatsapp_on', 1);
$wa_number = '';
if ($wa_on) {
$wa_number = trim((string) get_option('branch_messenger_whatsapp'));
if (false !== strpos($wa_number, 'wa.me/')) {
$wa_number = substr($wa_number, strpos($wa_number, 'wa.me/') + 6);
}
$wa_number = preg_replace('/[^0-9]/', '', $wa_number);
if ('' !== $wa_number && '8' === $wa_number[0] && 11 === strlen($wa_number)) {
$wa_number = '7' . substr($wa_number, 1);
}
}
// Фолбэк: телефон филиала.
if ('' === $wa_number && $phone_clean) {
$wa_number = preg_replace('/[^0-9]/', '', $phone_clean);
if ('8' === $wa_number[0] && 11 === strlen($wa_number)) {
$wa_number = '7' . substr($wa_number, 1);
}
}
$wa_url = ('' !== $wa_number) ? 'https://wa.me/' . $wa_number : '';
// ─── Профиль преподавателя (CF) ───
$direction = carbon_get_post_meta($tid, 'teacher_direction');
$subj = $direction;
$badge = carbon_get_post_meta($tid, 'teacher_badge');
$rating = carbon_get_post_meta($tid, 'teacher_rating');
$rating_num = is_numeric($rating) ? (float) $rating : 0.0;
$start_year = carbon_get_post_meta($tid, 'teacher_start_year');
$tenure = '';
if ($start_year && absint($start_year) > 1900) {
$tenure = max(0, (int) current_time('Y') - (int) $start_year);
}
$avatar_id = carbon_get_post_meta($tid, 'teacher_avatar');
$avatar_url = $avatar_id ? wp_get_attachment_url($avatar_id) : ''; // Schema Person.image
$avatar_alt = $avatar_id ? get_post_meta($avatar_id, '_wp_attachment_image_alt', true) : '';
if (empty($avatar_alt)) {
$avatar_alt = 'Преподаватель ' . $full_name . ' — школа «' . $branch_name . '» ' . $branch_city;
}
// image() = проверка наличия + готовый HTML, без отдельного url-запроса.
$avatar_img = $avatar_id ? wp_get_attachment_image(
(int) $avatar_id,
array( 600, 600 ),
false,
array(
'class' => 'ds-hero__photo',
'alt' => $avatar_alt,
'loading' => 'eager',
'decoding' => 'async',
'fetchpriority' => 'high', // LCP-изображение
)
) : '';
$avg_score = carbon_get_post_meta($tid, 'teacher_avg_score');
$seats_left = carbon_get_post_meta($tid, 'teacher_seats_left');
$group_size = carbon_get_post_meta($tid, 'teacher_group_size') ?: '2-6';
$avg_label = carbon_get_post_meta($tid, 'teacher_avg_label');
if (empty($avg_label)) {
$avg_label = 'Средний балл учеников';
}
$exam_label = carbon_get_post_meta($tid, 'teacher_exam_label') ?: 'нового набора';
$cta_primary = carbon_get_post_meta($tid, 'teacher_cta_primary') ?: 'Записаться на диагностику';
$sched_label = carbon_get_post_meta($tid, 'teacher_schedule_label') ?: 'Посмотреть расписание групп';
$sched_url = carbon_get_post_meta($tid, 'teacher_schedule_url');
$risk_note = carbon_get_post_meta($tid, 'teacher_risk_note');
if (empty($risk_note)) {
$risk_note = 'Перезвоним за 15 минут · Без обязательств';
}
$school_num = carbon_get_post_meta($tid, 'teacher_school_num');
$school_label = carbon_get_post_meta($tid, 'teacher_school_label');
if (empty($school_label)) {
$school_label = 'учеников продолжают обучение на следующий учебный год';
}
$exam_date = carbon_get_post_meta($tid, 'teacher_exam_date');
$scarcity_note = carbon_get_post_meta($tid, 'teacher_scarcity_note');
if (empty($scarcity_note)) {
$scarcity_note = 'Набор в группу идёт каждый месяц, но места ограничены.';
}
$about_text = carbon_get_post_meta($tid, 'teacher_about');
$education = carbon_get_post_meta($tid, 'teacher_education');
$add_education = carbon_get_post_meta($tid, 'teacher_add_education');
$video_html = carbon_get_post_meta($tid, 'teacher_video');
// Ссылка VK/YouTube → iframe. Пусто → блок скрыт.
if ($video_html && 0 !== strpos(ltrim($video_html), '<')) {
$video_url = trim($video_html);
if (preg_match('~vk\.com/video(-?\d+)_(\d+)~', $video_url, $vm)) {
$video_html = '<iframe src="https://vk.com/video_ext.php?oid=' . esc_attr($vm[1]) . '&id=' . esc_attr($vm[2]) . '&hd=2" width="853" height="480" allow="autoplay; encrypted-media; fullscreen; picture-in-picture;" frameborder="0" allowfullscreen></iframe>';
} elseif (preg_match('~(?:youtube\.com/(?:watch\?v=|embed/)|youtu\.be/)([\w-]{6,})~', $video_url, $ym)) {
$video_html = '<iframe src="https://www.youtube.com/embed/' . esc_attr($ym[1]) . '" width="853" height="480" allow="autoplay; encrypted-media; fullscreen; picture-in-picture;" frameborder="0" allowfullscreen></iframe>';
}
}
$license = carbon_get_post_meta($tid, 'teacher_license');
if (empty($license)) {
$license = 'Частная школа «' . $branch_name . '» работает по лицензии на образовательную деятельность (бессрочная). Копия лицензии и реквизиты — по запросу у администратора.';
}
// Счётчик реальных отзывов.
$review_count = function_exists('dekart_teacher_review_count') ? dekart_teacher_review_count($tid) : 0;
// Подзаголовок hero — из админки (вкладка Hero); пусто — авто-сборка.
$hero_subtitle = trim((string) carbon_get_post_meta($tid, 'teacher_hero_subtitle'));
if ('' === $hero_subtitle) {
$hero_subtitle = ( $subj ? $subj : 'Обучение' ) . ' — мини-группы ' . $group_size . ' чел. · ' . $exam_label . ' · школа «' . $branch_name . '» ' . $branch_city_prep;
}
// ─── Шаги «Как проходит первое занятие» ───
$steps = (array) carbon_get_post_meta($tid, 'teacher_steps');
if (empty($steps) || ! is_array($steps)) {
$steps = array(
array( 'step_title' => 'Заявка', 'step_text' => 'Оставляете заявку — администратор перезванивает за 15 минут и отвечает на вопросы.' ),
array( 'step_title' => 'Бесплатная диагностика (30 мин)', 'step_text' => 'Определяем уровень знаний и разбираем «слабые места».' ),
array( 'step_title' => 'Подбор группы по уровню', 'step_text' => 'Подбираем мини-группу 26 человек под уровень ребёнка.' ),
array( 'step_title' => 'Первое занятие', 'step_text' => 'Знакомство с преподавателем и форматом. Ребёнок пробует — вы решаете.' ),
array( 'step_title' => 'Обратная связь родителю', 'step_text' => 'После каждого занятия — короткий отчёт: что прошли, что получается.' ),
);
}
// ─── Сегменты «Для кого» ───
$segments = (array) carbon_get_post_meta($tid, 'teacher_segments');
if (empty($segments) || ! is_array($segments)) {
$segments = array(
array( 'segment_title' => 'Начинаете заниматься', 'segment_text' => 'Системные занятия: объясняем материал, закрепляем на практике, проверяем понимание. Без стресса и зубрёжки.' ),
array( 'segment_title' => 'Отстали по программе', 'segment_text' => 'Закрываем пробелы и возвращаем уверенность. Маленькая группа — каждому хватает внимания.' ),
array( 'segment_title' => 'Хотите больше школьной программы', 'segment_text' => 'Углубляем знания, учим думать, а не запоминать. Мини-группа держит темп и азарт.' ),
);
}
$segment_4_title = 'Уже занимались с репетитором, но нет результата?';
$segment_4_text = 'Частая ситуация: деньги потрачены, а результата нет. В мини-группе другой механизм — соревнование, методика и куратор. Приходите на бесплатную диагностику и сравните сами.';
// ─── Кейсы (табы) ───
$cases = (array) carbon_get_post_meta($tid, 'teacher_cases');
// ─── FAQ: формат + общие вопросы ───
$faq_extra = (array) carbon_get_post_meta($tid, 'teacher_faq_extra');
$faq_items = array();
if (empty($faq_extra)) {
$faq_items[] = array(
'q' => 'Чем мини-группа лучше репетитора?',
'a' => 'В мини-группе 26 человек преподаватель видит каждого, но у детей появляется азарт, здоровая конкуренция и живое обсуждение. Стоимость ниже репетитора, а дисциплина выше — пропускать занятия не хочется.',
);
$faq_items[] = array(
'q' => 'Что если ребёнок стесняется заниматься с другими?',
'a' => 'Начинаем с диагностики и подбираем группу по уровню и темпераменту. Первые занятия преподаватель мягко вовлекает ребёнка — обычно через 23 занятия стеснение уходит.',
);
} else {
foreach ($faq_extra as $fx) {
if (! empty($fx['faq_q']) && ! empty($fx['faq_a'])) {
$faq_items[] = array( 'q' => $fx['faq_q'], 'a' => $fx['faq_a'] );
}
}
}
$legacy_questions = (array) carbon_get_post_meta($tid, 'questions');
foreach ($legacy_questions as $lq) {
if (! empty($lq['questions_question']) && ! empty($lq['questions_answer'])) {
$faq_items[] = array( 'q' => $lq['questions_question'], 'a' => $lq['questions_answer'] );
}
}
// ─── Дни до экзамена (полоса дефицита) ───
// «Сегодня» = 0, «завтра» = 1; прошедшая дата → блок скрыт.
$days_left = '';
if ($exam_date && preg_match('/^\d{4}-\d{2}-\d{2}$/', $exam_date)) {
$tz = wp_timezone();
$exam_ts = (int) ( new DateTime($exam_date, $tz) )->format('U');
$today_ts = (int) ( new DateTime('now', $tz) )->setTime(0, 0)->format('U');
$diff = (int) round( ( $exam_ts - $today_ts ) / DAY_IN_SECONDS );
if ($diff >= 0) {
$days_left = (string) $diff;
}
}
// ─── Микроразметка (единый @graph) ───
// Пустые свойства не выводим (Google ругается на пустые обязательные поля).
$teachers_page = get_page_by_path('our-teachers');
$page_url = get_permalink($tid);
$org_id = home_url('/') . '#org';
$person_id = $page_url . '#person';
$org_logo = '';
$branch_logo_id = absint(get_option('branch_logo'));
if ($branch_logo_id) {
$org_logo = wp_get_attachment_url($branch_logo_id);
}
if (! $org_logo && carbon_get_theme_option('site_logo')) {
$org_logo = wp_get_attachment_url(carbon_get_theme_option('site_logo'));
}
$branch_email = get_option('branch_email') ?: carbon_get_theme_option('site_email');
// ── EducationalOrganization ──
$org = array(
'@type' => 'EducationalOrganization',
'@id' => $org_id,
'name' => $branch_name,
'url' => home_url('/'),
);
if ($org_logo) {
$org['logo'] = $org_logo;
}
if ($branch_phone) {
$org['telephone'] = $branch_phone;
}
if ($branch_email) {
$org['email'] = $branch_email;
}
// Адрес филиала: branch_* → фолбэк site_*.
$org_addr = array();
$org_street = get_option('branch_address') ?: carbon_get_theme_option('site_address');
$org_city = get_option('branch_city') ?: carbon_get_theme_option('site_city');
$org_region = get_option('branch_region') ?: '';
$org_zip = get_option('branch_postal_code') ?: get_option('branch_zip') ?: '';
if (! empty($org_street)) { $org_addr['streetAddress'] = $org_street; }
if (! empty($org_city)) { $org_addr['addressLocality'] = $org_city; }
if (! empty($org_region)) { $org_addr['addressRegion'] = $org_region; }
if (! empty($org_zip)) { $org_addr['postalCode'] = $org_zip; }
if (! empty($org_addr)) {
$org_addr = array_merge(array('@type' => 'PostalAddress', 'addressCountry' => 'RU'), $org_addr);
$org['address'] = $org_addr;
}
// Лицензия — из настроек филиала.
$org_license = get_option('branch_license') ?: carbon_get_theme_option('site_license');
if (! empty($org_license)) {
$org['hasCredential'] = array(
'@type' => 'EducationalOccupationalCredential',
'name' => $org_license,
);
}
// ── Person (преподаватель) ──
// Каталог программ филиала: название → url/price (цена — только для Course.offers в микроразметке).
$branch_programs_by_name = array();
foreach ((array) get_option('branch_programs', array()) as $bp) {
$pn = trim((string) ( $bp['name'] ?? '' ));
if ('' !== $pn) {
$branch_programs_by_name[ $pn ] = array(
'price' => trim((string) ( $bp['price'] ?? '' )),
'url' => trim((string) ( $bp['url'] ?? '' )),
);
}
}
// Предметы: title → курс; topics → чипы. URL/цена — из каталога филиала (fallback — CF преподавателя).
$teacher_subjects = (array) carbon_get_post_meta($tid, 'teacher_subjects');
$subject_items = array(); // [title => ['name', 'url', 'price', 'topics[]']] без дубликатов
foreach ($teacher_subjects as $ts) {
$sn = trim((string) ( $ts['teacher_subjects_title'] ?? '' ));
if ('' === $sn) {
continue;
}
if (isset($subject_items[$sn])) {
continue; // дубликат заголовка — пропускаем
}
$topics = array();
$topics_raw = trim((string) ( $ts['teacher_subjects_topics'] ?? '' ));
if ('' !== $topics_raw) {
foreach (preg_split('/\r\n|\r|\n/', $topics_raw) as $tp) {
$tp = trim($tp);
if ('' !== $tp) {
$topics[] = $tp;
}
}
}
$prog = $branch_programs_by_name[ $sn ] ?? null;
$subject_items[$sn] = array(
'name' => $sn,
'url' => ( $prog && '' !== $prog['url'] ) ? $prog['url'] : trim((string) ( $ts['teacher_subjects_url'] ?? '' )),
'price' => ( $prog && '' !== $prog['price'] ) ? $prog['price'] : '',
'topics' => $topics,
);
}
$subject_names = array_keys($subject_items);
// ─── Общие данные из настроек филиала (не дублируются в CF преподавателя) ───
$branch_price = get_option('branch_price');
$branch_geo_areas = get_option('branch_area_served');
$geo_walk = get_option('branch_logistics_walk');
$geo_parking = get_option('branch_logistics_parking');
$geo_schools = get_option('branch_logistics_schools');
// ─── Результаты учеников: CF или авто-сборка ───
$cf_results = carbon_get_post_meta($tid, 'teacher_results');
$results = array();
if (is_array($cf_results) && ! empty($cf_results)) {
$results = array_values($cf_results);
} else {
if (! empty($school_num)) { $results[] = array( 'result_title' => (string) $school_num, 'result_text' => $school_label ); }
if ($avg_score) { $results[] = array( 'result_title' => $avg_score, 'result_text' => $avg_label ); }
if ($tenure) { $results[] = array( 'result_title' => $tenure . ' лет', 'result_text' => 'педагогический стаж преподавателя' ); }
if ($review_count > 0) { $results[] = array( 'result_title' => (string) $review_count, 'result_text' => 'реальных отзывов родителей о преподавателе' ); }
}
$person = array(
'@type' => 'Person',
'@id' => $person_id,
'name' => $full_name,
'url' => $page_url,
'worksFor' => array('@id' => $org_id),
);
if ($direction) {
$person['jobTitle'] = $direction;
}
if ($avatar_url) {
$person['image'] = $avatar_url;
}
if ($about_text) {
$person['description'] = wp_strip_all_tags($about_text);
}
if (! empty($subject_names)) {
$person['knowsAbout'] = $subject_names;
}
$diploma = trim((string) carbon_get_post_meta($tid, 'teacher_diploma'));
if ('' !== $diploma) {
$person['alumniOf'] = array('@type' => 'CollegeOrUniversity', 'name' => $diploma);
}
// ── Рейтинг преподавателя ──
// Среднее реальных отзывов (SQL-агрегат); CF teacher_rating — фолбэк, когда отзывов нет.
$sp_avg_num = function_exists('dekart_teacher_review_avg')
? (float) dekart_teacher_review_avg($tid)
: 0.0;
$sp_avg = $sp_avg_num > 0 ? number_format($sp_avg_num, 1, '.', '') : '';
$rating_num = $sp_avg_num > 0 ? $sp_avg_num : ( is_numeric($rating) ? (float) $rating : 0.0 );
// AggregateRating не размечаем: невалиден для Person в schema.org, Google не даёт
// по нему rich results. Средний балл — только UI; в Schema — отдельные Review с reviewRating.
// Review не размечаем: Google не поддерживает Person среди itemReviewed для review
// rich results. Отзывы остаются в видимом HTML (reviews-link) — там их место.
// ── Course — по каждому предмету (предмет + мини-группа) ──
// Person и Org объявляются один раз (@id); в курсах — ссылки.
$build_course = function ( $name, $cid, $availability = null, $description = '', $price = '' ) use ( $page_url, $org_id, $person_id, $group_size, $full_name, $branch_price ) {
$course = array(
'@type' => 'Course',
'@id' => $page_url . '#course-' . $cid,
'name' => $name,
'description' => ( '' !== $description )
? $description
: 'Курс «' . $name . '» в мини-группе ' . $group_size . ' человек. Преподаватель — ' . $full_name . '.',
'provider' => array('@id' => $org_id),
'hasCourseInstance' => array(
'@type' => 'CourseInstance',
'courseMode' => 'Onsite',
'instructor' => array('@id' => $person_id),
),
'offers' => array(
'@type' => 'Offer',
'category' => 'Мини-группа 2' . $group_size . ' человек',
),
);
// Цена — только микроразметка: из каталога программы → фолбэк branch_price;
// Schema требует число — извлекаем из строки вида «от 1 290 ₽».
$offer_price = ( '' !== (string) $price ) ? $price : $branch_price;
$offer_price_norm = preg_replace('/\s+/u', '', (string) $offer_price);
if (preg_match('/\d+(?:[.,]\d+)?/', $offer_price_norm, $pm)) {
$course['offers']['price'] = str_replace(',', '.', $pm[0]);
$course['offers']['priceCurrency'] = 'RUB';
}
if (null !== $availability) {
$course['offers']['availability'] = $availability;
}
return $course;
};
$courses = array();
if (! empty($subject_names)) {
foreach ($subject_names as $i => $cn) {
// Availability: >0 → Limited, =0 → SoldOut, пусто → не указываем.
$availability = null;
if ('' !== (string) $seats_left) {
$availability = ( (int) $seats_left > 0 )
? 'https://schema.org/LimitedAvailability'
: 'https://schema.org/SoldOut';
}
$courses[] = $build_course($cn, $i + 1, $availability, '', $subject_items[$cn]['price']);
}
} else {
$courses[] = $build_course( ( $subj ? $subj : 'Обучение' ) . ' — мини-группы ' . $group_size . ' чел.', 1 );
}
// ── FAQPage ──
$schema_faq = array();
foreach ($faq_items as $fq) {
$schema_faq[] = array(
'@type' => 'Question',
'name' => $fq['q'],
'acceptedAnswer' => array('@type' => 'Answer', 'text' => $fq['a']),
);
}
// ── BreadcrumbList ──
$crumb_parents = array(array('name' => 'Главная', 'url' => home_url('/')));
if ($teachers_page) {
$crumb_parents[] = array('name' => 'Преподаватели', 'url' => get_permalink($teachers_page));
}
$crumb_parents[] = array('name' => $full_name);
$breadcrumbs = array();
foreach ($crumb_parents as $i => $p) {
$item = array('@type' => 'ListItem', 'position' => $i + 1, 'name' => $p['name']);
if (! empty($p['url'])) {
$item['item'] = $p['url'];
}
$breadcrumbs[] = $item;
}
// ── @graph ──
$org['employee'] = array(array('@id' => $person_id));
$schema_graph = array($org, $person);
foreach ($courses as $c) {
$schema_graph[] = $c;
}
if (! empty($schema_faq)) {
$schema_graph[] = array('@type' => 'FAQPage', 'mainEntity' => $schema_faq);
}
$schema_graph[] = array('@type' => 'BreadcrumbList', 'itemListElement' => $breadcrumbs);
?>
<main class="teacher-single">
<?php get_template_part('template-parts/svg-sprite'); ?>
<?php
// ─────────────────────────── HERO ───────────────────────────
?>
<section class="section-bg ds-hero teacher-single__hero" data-bg="hero" aria-labelledby="teacher-single-title">
<div class="ds-container">
<div class="ds-hero__inner">
<div class="ds-hero__content">
<nav class="ds-breadcrumbs teacher-single__breadcrumbs" aria-label="Хлебные крошки" itemscope itemtype="https://schema.org/BreadcrumbList">
<span itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<a itemprop="item" href="<?php echo esc_url(home_url('/')); ?>"><span itemprop="name">Главная</span></a>
<meta itemprop="position" content="1">
</span>
<span aria-hidden="true">/</span>
<?php if ($teachers_page) : ?>
<span itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<a itemprop="item" href="<?php echo esc_url(get_permalink($teachers_page)); ?>"><span itemprop="name">Преподаватели</span></a>
<meta itemprop="position" content="2">
</span>
<span aria-hidden="true">/</span>
<?php endif; ?>
<span class="ds-breadcrumbs__current" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<span itemprop="name"><?php echo esc_html($full_name); ?></span>
<meta itemprop="position" content="3">
</span>
</nav>
<?php if ($badge) : ?>
<span class="teacher-single__badge"><?php echo esc_html($badge); ?></span>
<?php endif; ?>
<h1 id="teacher-single-title" class="ds-hero__h1 teacher-single__h1"><?php echo esc_html($full_name); ?></h1>
<?php if ($hero_subtitle) : ?>
<p class="ds-hero__subtitle teacher-single__subtitle">
<?php echo esc_html($hero_subtitle); ?>
</p>
<?php endif; ?>
<?php if ($rating_num > 0 || $tenure) : ?>
<div class="teacher-single__hero-facts">
<?php if ($rating_num > 0) : ?>
<span class="teacher-single__hero-fact">
<span class="teacher-single__stars" aria-hidden="true">
<?php for ($s = 1; $s <= 5; $s++) : ?>
<svg class="<?php echo $s <= round($rating_num) ? 'is-filled' : ''; ?>" width="16" height="16" viewBox="0 0 20 20" fill="currentColor"><path d="M10 1l2.39 4.84 5.34.78-3.87 3.77.92 5.34L10 13.27l-4.78 2.51.92-5.34L2.27 6.6l5.34-.78L10 1z"/></svg>
<?php endfor; ?>
</span>
<?php echo esc_html(rtrim(rtrim(number_format($rating_num, 1), '0'), '.')); ?>
<?php if ($review_count > 0) : ?><span class="teacher-single__hero-rating-count">(<?php echo esc_html($review_count); ?>)</span><?php endif; ?>
</span>
<?php endif; ?>
<?php if ($tenure) : ?>
<span class="teacher-single__hero-fact">Стаж — <?php echo esc_html($tenure); ?> лет</span>
<?php endif; ?>
<span class="teacher-single__hero-fact">Мини-группа <?php echo esc_html($group_size); ?> чел.</span>
</div>
<?php endif; ?>
<div class="teacher-single__hero-cta">
<button type="button" class="teacher-single__btn teacher-single__btn--primary btn-write open-bitrix-form">
<?php echo esc_html($cta_primary); ?>
</button>
<?php if ($sched_url) : ?>
<a class="teacher-single__btn teacher-single__btn--ghost" href="<?php echo esc_url($sched_url); ?>">
<?php echo esc_html($sched_label); ?>
</a>
<?php endif; ?>
</div>
<p class="teacher-single__risk-note"><?php echo esc_html($risk_note); ?></p>
<noscript>
<p class="ds-hero__cta-fallback">Позвоните: <a href="tel:<?php echo esc_attr($phone_clean ?: '+74951206699'); ?>"><?php echo esc_html($branch_phone ?: '+7 (495) 120-66-99'); ?></a></p>
</noscript>
</div>
<div class="ds-hero__visual teacher-single__visual">
<?php if ($avatar_img) : ?>
<div class="ds-hero__photo-wrap">
<div class="ds-hero__photo-frame teacher-single__photo-frame">
<?php echo $avatar_img; ?>
</div>
<div class="ds-hero__photo-ring" aria-hidden="true"></div>
</div>
<?php endif; ?>
</div>
</div>
</div>
</section>
<?php
// ─────────────────── ЦИФРЫ ───────────────────
// Карточки — только из CF complex teacher_metrics; пусто — секция скрыта.
$metrics = array();
$metric_cards = (array) carbon_get_post_meta($tid, 'teacher_metrics');
if (! empty($metric_cards) && is_array($metric_cards)) {
foreach ($metric_cards as $mc) {
$mn = trim((string) ( $mc['metric_num'] ?? '' ));
if ('' === $mn) {
continue;
}
$metrics[] = array(
'num' => $mn,
'label' => trim((string) ( $mc['metric_text'] ?? '' )),
);
}
}
if (! empty($metrics)) :
?>
<section class="teacher-single__metrics section-bg reveal" data-bg="teacher-metrics" aria-label="Цифры">
<div class="container">
<div class="teacher-single__metrics-grid<?php echo count($metrics) < 3 ? ' is-few' : ''; ?>">
<?php foreach ($metrics as $m) : ?>
<div class="teacher-single__metric">
<div class="teacher-single__metric-num"><?php echo esc_html($m['num']); ?></div>
<div class="teacher-single__metric-label"><?php echo esc_html($m['label']); ?></div>
</div>
<?php endforeach; ?>
</div>
</div>
</section>
<?php endif; ?>
<?php
// ─────────────────── ПОЛОСА ДЕФИЦИТА ───────────────────
if ($days_left !== '' || ( $seats_left && (int) $seats_left > 0 )) :
?>
<section class="teacher-single__scarcity section-bg reveal" data-bg="teacher-scarcity" aria-label="Осталось мест">
<div class="container">
<div class="teacher-single__scarcity-inner">
<?php if ($days_left !== '') : ?>
<div class="teacher-single__scarcity-item">
<span class="teacher-single__scarcity-num" data-countdown="<?php echo esc_attr($days_left); ?>"><?php echo esc_html($days_left); ?></span>
<span class="teacher-single__scarcity-label">дней до <?php echo esc_html($exam_label); ?></span>
</div>
<?php endif; ?>
<?php if ($seats_left && (int) $seats_left > 0) : ?>
<div class="teacher-single__scarcity-item">
<span class="teacher-single__scarcity-num is-hot"><?php echo esc_html($seats_left); ?></span>
<span class="teacher-single__scarcity-label">места в группе</span>
</div>
<?php endif; ?>
<p class="teacher-single__scarcity-note"><?php echo esc_html($scarcity_note); ?></p>
</div>
</div>
</section>
<?php endif; ?>
<?php if (! empty($subject_items)) : ?>
<?php
// ─────────────────── ПРОГРАММЫ (H2-секция на курс) ───────────────────
// Якорь #course-N совпадает с @id в микроразметке. Цена на странице не выводится.
?>
<section class="teacher-single__courses section-bg reveal" data-bg="teacher-courses" aria-labelledby="teacher-courses-title">
<div class="container">
<div class="section-header--left">
<h2 id="teacher-courses-title" class="bento-h2">Программы и направления</h2>
<p class="bento-p"><?php echo esc_html($full_name); ?> ведёт занятия по направлениям в мини-группах <?php echo esc_html($group_size); ?> человек — выберите программу.</p>
</div>
<div class="teacher-single__courses-grid">
<?php $course_i = 1; ?>
<?php foreach ($subject_items as $si) :
$course_anchor = 'course-' . $course_i;
?>
<article class="teacher-single__course" id="<?php echo esc_attr($course_anchor); ?>">
<div class="teacher-single__course-head">
<h2 class="teacher-single__course-title">
<?php echo esc_html($si['name']); ?> <?php echo esc_html($branch_city_prep); ?>
</h2>
<?php if (! empty($si['url'])) : ?>
<a class="teacher-single__course-link" href="<?php echo esc_url($si['url']); ?>">Подробнее о программе&nbsp;→</a>
<?php endif; ?>
</div>
<?php if (! empty($si['topics'])) : ?>
<ul class="teacher-single__course-topics">
<?php foreach ($si['topics'] as $tp) : ?>
<li class="teacher-single__course-topic"><?php echo esc_html($tp); ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<div class="teacher-single__course-foot">
<button type="button" class="teacher-single__btn teacher-single__btn--primary btn-write open-bitrix-form">
<?php echo esc_html($cta_primary); ?>
</button>
</div>
</article>
<?php $course_i++; ?>
<?php endforeach; ?>
</div>
</div>
</section>
<?php endif; ?>
<?php
// ─────────────────── СОЦИАЛЬНОЕ ДОКАЗАТЕЛЬСТВО ───────────────────
// Рейтинг преподавателя — $sp_avg (рассчитан выше), школы — из опций филиала.
$branch_avg = (string) get_option('branch_avg_rating', '');
$branch_cnt = (string) get_option('branch_ext_review_count', '');
if ('' !== $sp_avg || $branch_avg || $branch_cnt) :
?>
<section class="teacher-single__social-proof section-bg reveal" data-bg="teacher-social-proof" aria-label="Отзывы родителей">
<div class="container">
<div class="teacher-single__social-proof-inner">
<?php if ('' !== $sp_avg) : ?>
<div class="teacher-single__sp-item">
<span class="teacher-single__sp-stars" aria-hidden="true">
<?php for ($sp_i = 1; $sp_i <= 5; $sp_i++) : ?>
<svg class="<?php echo $sp_i <= (int) round((float) $sp_avg) ? 'is-filled' : ''; ?>" width="18" height="18" viewBox="0 0 20 20" fill="currentColor"><path d="M10 1l2.39 4.84 5.34.78-3.87 3.77.92 5.34L10 13.27l-4.78 2.51.92-5.34L2.27 6.6l5.34-.78L10 1z"/></svg>
<?php endfor; ?>
</span>
<strong class="teacher-single__sp-num"><?php echo esc_html($sp_avg); ?></strong>
<span class="teacher-single__sp-text">оценка преподавателя по отзывам родителей</span>
<?php if ($review_count > 0) : ?>
<a class="teacher-single__sp-link" href="#reviews"><?php echo esc_html($review_count); ?> отзывов о преподавателе →</a>
<?php endif; ?>
</div>
<?php endif; ?>
<?php if ($branch_avg || $branch_cnt) : ?>
<div class="teacher-single__sp-item">
<strong class="teacher-single__sp-num"><?php echo esc_html($branch_avg); ?></strong>
<span class="teacher-single__sp-text">рейтинг школы в Яндекс Картах</span>
<?php if ($branch_cnt) : ?>
<span class="teacher-single__sp-link"><?php echo esc_html($branch_cnt); ?> отзывов на внешних площадках</span>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
</div>
</section>
<?php endif; ?>
<?php
// ─────────────────── СЕГМЕНТЫ «ДЛЯ КОГО» ───────────────────
?>
<section class="teacher-single__segments section-bg reveal" data-bg="teacher-segments" aria-labelledby="teacher-segments-title">
<div class="container">
<div class="section-header--left">
<h2 id="teacher-segments-title" class="bento-h2">Кому подойдут занятия</h2>
<p class="bento-p">Формат мини-группы закрывает три разные задачи — выберите свою.</p>
</div>
<div class="teacher-single__segments-grid">
<?php $seg_num = 0; ?>
<?php foreach ($segments as $i => $seg) :
if ($i >= 3) {
break;
}
$s_title = $seg['segment_title'] ?? '';
$s_text = $seg['segment_text'] ?? '';
if (! $s_title) {
continue;
}
$seg_num++;
?>
<article class="teacher-single__segment-card">
<span class="teacher-single__segment-icon" aria-hidden="true"><?php echo esc_html(str_pad((string) $seg_num, 2, '0', STR_PAD_LEFT)); ?></span>
<h3 class="teacher-single__segment-title"><?php echo esc_html($s_title); ?></h3>
<p class="teacher-single__segment-text"><?php echo esc_html($s_text); ?></p>
</article>
<?php endforeach; ?>
</div>
<details class="teacher-single__spoiler">
<summary class="teacher-single__spoiler-summary"><?php echo esc_html($segment_4_title); ?></summary>
<div class="teacher-single__spoiler-body">
<p><?php echo esc_html($segment_4_text); ?></p>
<button type="button" class="teacher-single__btn teacher-single__btn--primary btn-write open-bitrix-form">
<?php echo esc_html($cta_primary); ?>
</button>
</div>
</details>
</div>
</section>
<?php
// ─────────────────── ИЗМЕРИМЫЕ РЕЗУЛЬТАТЫ (отдельно от «Кому подойдут») ───────────────────
if (! empty($results)) :
?>
<section class="teacher-single__results section-bg reveal" data-bg="teacher-results" aria-labelledby="teacher-results-title">
<div class="container">
<div class="section-header--left">
<h2 id="teacher-results-title" class="bento-h2">Измеримые результаты учеников</h2>
<p class="bento-p">Не обещания, а факты — что меняется в знаниях и успеваемости после занятий.</p>
</div>
<div class="teacher-single__results-grid">
<?php foreach ($results as $rs) :
$rt = trim((string) ( $rs['result_title'] ?? '' ));
if ('' === $rt) {
continue;
}
?>
<div class="teacher-single__result">
<div class="teacher-single__result-num"><?php echo esc_html($rt); ?></div>
<div class="teacher-single__result-text"><?php echo esc_html($rs['result_text'] ?? ''); ?></div>
</div>
<?php endforeach; ?>
</div>
</div>
</section>
<?php endif; ?>
<?php
// ─────────────────── ЛИЧНАЯ ИСТОРИЯ + КАК ПРОХОДИТ ЗАНЯТИЕ ───────────────────
if ($about_text) :
?>
<section class="teacher-single__story section-bg reveal" data-bg="teacher-story" aria-labelledby="teacher-story-title">
<div class="container">
<div class="teacher-single__story-grid">
<div class="teacher-single__story-about">
<h2 id="teacher-story-title" class="bento-h2">О себе</h2>
<div class="teacher-single__story-text"><?php echo wp_kses_post(wpautop($about_text)); ?></div>
</div>
<div class="teacher-single__story-steps">
<h2 class="bento-h2">Как проходит первое занятие</h2>
<ol class="teacher-single__timeline">
<?php $step_num = 0; ?>
<?php foreach ($steps as $i => $step) :
$st_title = $step['step_title'] ?? '';
$st_text = $step['step_text'] ?? '';
if (! $st_title) {
continue;
}
$step_num++;
?>
<li class="teacher-single__timeline-item">
<span class="teacher-single__timeline-num" aria-hidden="true"><?php echo esc_html($step_num); ?></span>
<div class="teacher-single__timeline-content">
<h3><?php echo esc_html($st_title); ?></h3>
<?php if ($st_text) : ?><p><?php echo esc_html($st_text); ?></p><?php endif; ?>
</div>
</li>
<?php endforeach; ?>
</ol>
</div>
</div>
</div>
</section>
<?php endif; ?>
<?php if ($video_html) : ?>
<section class="teacher-single__video section-bg reveal" data-bg="teacher-video" aria-labelledby="teacher-video-title">
<div class="container">
<h2 id="teacher-video-title" class="bento-h2">Видео-приветствие</h2>
<p class="bento-p">Посмотрите, как преподаватель общается — представьте его в роли наставника вашего ребёнка.</p>
<div class="teacher-single__video-frame">
<?php echo wp_kses_post($video_html); ?>
</div>
</div>
</section>
<?php endif; ?>
<?php
// ─────────────────── КЕЙСЫ (ТАБЫ 9/11) ───────────────────
$case_tabs = array();
if (! empty($cases) && is_array($cases)) {
$case_tabs = array_values(array_unique(array_filter(array_map(function ($c) {
return trim((string) ( $c['case_tab'] ?? '' ));
}, $cases))));
}
if (! empty($case_tabs)) :
?>
<section class="teacher-single__cases section-bg reveal" data-bg="teacher-cases" aria-labelledby="teacher-cases-title">
<div class="container">
<h2 id="teacher-cases-title" class="bento-h2">Результаты учеников</h2>
<div class="teacher-single__cases-tabs" role="tablist" aria-label="Класс">
<?php foreach ($case_tabs as $ci => $tab) :
$tab_id = sanitize_title($tab) . '-' . $ci;
if ('' === trim($tab_id, '-')) {
$tab_id = 'tab-' . $ci;
}
?>
<button type="button" role="tab" id="case-tab-<?php echo esc_attr($tab_id); ?>" aria-controls="case-panel-<?php echo esc_attr($tab_id); ?>" aria-selected="<?php echo 0 === $ci ? 'true' : 'false'; ?>" class="teacher-single__case-tab<?php echo 0 === $ci ? ' is-active' : ''; ?>" data-case-tab="<?php echo esc_attr($tab); ?>">
<?php echo esc_html($tab); ?> класс
</button>
<?php endforeach; ?>
</div>
<?php foreach ($case_tabs as $ci => $tab) :
$tab_id = sanitize_title($tab) . '-' . $ci;
if ('' === trim($tab_id, '-')) {
$tab_id = 'tab-' . $ci;
}
?>
<div role="tabpanel" id="case-panel-<?php echo esc_attr($tab_id); ?>" aria-labelledby="case-tab-<?php echo esc_attr($tab_id); ?>" class="teacher-single__case-panel<?php echo 0 === $ci ? ' is-active' : ''; ?>" data-case-panel="<?php echo esc_attr($tab); ?>">
<div class="teacher-single__cases-grid">
<?php foreach ($cases as $case) :
if (trim((string) ( $case['case_tab'] ?? '' )) !== $tab || empty($case['case_text'])) {
continue;
}
?>
<div class="teacher-single__case-card">
<span class="teacher-single__case-mark" aria-hidden="true">“</span>
<p><?php echo esc_html($case['case_text']); ?></p>
</div>
<?php endforeach; ?>
</div>
</div>
<?php endforeach; ?>
</div>
</section>
<?php endif; ?>
<?php
// ─────────────────── ОБРАЗОВАНИЕ / СЕРТИФИКАТЫ ───────────────────
// Направления здесь не дублируем — они уже показаны выше в секции «Программы и направления».
$certificates = (array) carbon_get_post_meta($tid, 'certificates');
if ($education || $add_education || ! empty($certificates)) :
?>
<section class="teacher-single__edu section-bg reveal" data-bg="teacher-edu" aria-labelledby="teacher-edu-title">
<div class="container">
<h2 id="teacher-edu-title" class="bento-h2">Образование и опыт</h2>
<div class="teacher-single__edu-grid">
<?php if ($education || $add_education) : ?>
<div class="teacher-single__edu-col">
<?php if ($education) : ?>
<h3 class="teacher-single__edu-h">Образование</h3>
<div class="teacher-single__edu-text"><?php echo wp_kses_post($education); ?></div>
<?php endif; ?>
<?php if ($add_education) : ?>
<h3 class="teacher-single__edu-h">Повышение квалификации</h3>
<div class="teacher-single__edu-text"><?php echo wp_kses_post($add_education); ?></div>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
<?php if ($certificates) : ?>
<div class="teacher-single__cert-grid">
<?php foreach ($certificates as $cert) :
$c_id = $cert['certificates_foto'] ?? '';
$c_alt = $c_id ? get_post_meta((int) $c_id, '_wp_attachment_image_alt', true) : '';
// image() = проверка наличия + вывод, без отдельного url-запроса.
$c_img = $c_id ? wp_get_attachment_image(
(int) $c_id,
'medium',
false,
array(
'alt' => $c_alt ?: ('Диплом или сертификат — ' . $full_name),
'loading' => 'lazy',
'decoding' => 'async',
)
) : '';
if (! $c_img) {
continue;
}
?>
<figure class="teacher-single__cert">
<?php echo $c_img; ?>
</figure>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
</section>
<?php endif; ?>
<?php
// ─────────────────── FAQ (формат + общие) ───────────────────
if (! empty($faq_items)) :
?>
<section class="teacher-single__faq section-bg reveal" data-bg="teacher-faq" aria-labelledby="teacher-faq-title">
<div class="container">
<h2 id="teacher-faq-title" class="bento-h2">Вопросы и ответы</h2>
<div class="teacher-single__faq-list">
<?php foreach ($faq_items as $fi) : ?>
<details class="teacher-single__faq-item">
<summary><?php echo esc_html($fi['q']); ?></summary>
<p><?php echo esc_html($fi['a']); ?></p>
</details>
<?php endforeach; ?>
</div>
</div>
</section>
<?php endif; ?>
<?php
// ─── ОТЗЫВЫ О ПРЕПОДАВАТЕЛЕ (part reviews-link, как на главной) ───
$show_social_reviews = carbon_get_post_meta($tid, 'teacher_show_social_reviews');
if ('no' !== (string) $show_social_reviews) {
get_template_part('template-parts/reviews-link', null, array( 'teacher' => $tid ));
}
?>
<?php
// ─────────────────── ДОВЕРИЕ / ЛИЦЕНЗИЯ ───────────────────
?>
<section class="teacher-single__trust section-bg reveal" data-bg="teacher-trust" aria-labelledby="teacher-trust-title">
<div class="container">
<div class="teacher-single__trust-inner">
<span class="teacher-single__trust-shield" aria-hidden="true"><svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><use href="#icon-check"/></svg></span>
<div>
<h2 id="teacher-trust-title" class="bento-h2">Работаем официально</h2>
<p class="teacher-single__trust-text"><?php echo esc_html($license); ?></p>
</div>
</div>
</div>
</section>
<?php
// ─── ДРУГИЕ ПРЕПОДАВАТЕЛИ (общий блок сайта) ───
get_template_part('template-parts/teachers-cards');
?>
<?php
// ─────────────────── ГЕО-ПОКРЫТИЕ (из настроек филиала) ───────────────────
$geo_items = array();
if ('' !== (string) $branch_geo_areas) {
foreach (array_map('trim', explode(',', $branch_geo_areas)) as $ga) {
if ('' !== $ga) {
$geo_items[] = $ga;
}
}
}
if (! empty($geo_items) || $geo_walk || $geo_parking || $geo_schools) :
?>
<section class="teacher-single__geo section-bg reveal" data-bg="teacher-geo" aria-labelledby="teacher-geo-title">
<div class="container">
<div class="teacher-single__geo-inner">
<div class="teacher-single__geo-main">
<h2 id="teacher-geo-title" class="bento-h2">Принимаем детей из городов рядом</h2>
<p class="bento-p">Занятия проходят очно в школе «<?php echo esc_html($branch_name); ?>» — <?php echo esc_html($branch_city_prep); ?>. Добираться удобно из соседних городов.</p>
</div>
<?php if (! empty($geo_items)) : ?>
<ul class="teacher-single__geo-cities">
<?php foreach ($geo_items as $gc) : ?>
<li><?php echo esc_html($gc); ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<?php if ($geo_walk || $geo_parking || $geo_schools) : ?>
<ul class="teacher-single__geo-logistics">
<?php if ($geo_walk) : ?>
<li><span class="teacher-single__geo-pin" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0Z"/><circle cx="12" cy="10" r="3"/></svg></span><?php echo esc_html($geo_walk); ?></li>
<?php endif; ?>
<?php if ($geo_parking) : ?>
<li><span class="teacher-single__geo-pin" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0Z"/><circle cx="12" cy="10" r="3"/></svg></span><?php echo esc_html($geo_parking); ?></li>
<?php endif; ?>
<?php if ($geo_schools) : ?>
<li><span class="teacher-single__geo-pin" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0Z"/><circle cx="12" cy="10" r="3"/></svg></span><?php echo esc_html($geo_schools); ?></li>
<?php endif; ?>
</ul>
<?php endif; ?>
</div>
</div>
</section>
<?php endif; ?>
<?php
// ─────────────────── ФИНАЛЬНЫЙ CTA ───────────────────
?>
<section class="teacher-single__final section-bg reveal" data-bg="teacher-final" aria-labelledby="teacher-final-title">
<div class="container">
<div class="teacher-single__final-inner">
<h2 id="teacher-final-title" class="bento-h2">Запишитесь на бесплатную диагностику</h2>
<p class="teacher-single__final-text">Познакомимся, проверим уровень ребёнка и подберём мини-группу <?php echo esc_html($group_size); ?> человек. Перезвоним за 15 минут.</p>
<div class="teacher-single__hero-cta">
<button type="button" class="teacher-single__btn teacher-single__btn--primary btn-write open-bitrix-form">
<?php echo esc_html($cta_primary); ?>
</button>
<?php if ($branch_phone) : ?>
<a class="teacher-single__btn teacher-single__btn--ghost" href="tel:<?php echo esc_attr($phone_clean); ?>">
<?php echo esc_html($branch_phone); ?>
</a>
<?php endif; ?>
</div>
<p class="teacher-single__risk-note"><?php echo esc_html($risk_note); ?></p>
</div>
</div>
</section>
<?php
// ─── КОНТАКТЫ / АДРЕС ───
get_template_part('template-parts/contacts');
// ─── ЭКСПЕРТНОСТЬ (E-E-A-T): автор — преподаватель, под картой ───
$teacher_creds = trim(implode(', ', array_filter(array(
$direction ?: '',
($tenure ? 'педагогический стаж ' . $tenure . ' лет' : ''),
))));
get_template_part('template-parts/author-eaat', null, array(
'author_name' => $full_name,
'author_creds' => $teacher_creds,
));
?>
<?php
// ─────────────────── STICKY CTA (мобильный) ───────────────────
?>
<div class="teacher-single__sticky" hidden>
<div class="teacher-single__sticky-inner">
<button type="button" class="teacher-single__btn teacher-single__btn--primary btn-write open-bitrix-form">
<?php echo esc_html($cta_primary); ?>
</button>
<?php if ($wa_url) : ?>
<a class="teacher-single__sticky-icon" href="<?php echo esc_url($wa_url); ?>" target="_blank" rel="noopener nofollow" aria-label="Написать в WhatsApp">
<svg width="22" height="22" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2a10 10 0 0 0-8.6 15L2 22l5.2-1.4A10 10 0 1 0 12 2Zm0 18.2a8.2 8.2 0 0 1-4.2-1.2l-.3-.2-3.1.8.8-3-.2-.3a8.2 8.2 0 1 1 7 3.9Zm4.5-6.1c-.2-.1-1.5-.7-1.7-.8-.2-.1-.4-.1-.6.1-.2.3-.6.8-.8 1-.1.2-.3.2-.5.1a6.7 6.7 0 0 1-3.4-3c-.3-.4 0-.5.2-.7l.4-.5c.1-.2.1-.3 0-.5l-.8-1.9c-.2-.5-.4-.4-.6-.4h-.5c-.2 0-.5.1-.7.3-.2.3-.9.9-.9 2.2s.9 2.5 1.1 2.7c.1.2 1.8 2.8 4.4 3.9 2.6 1.1 2.6.7 3.1.7.5 0 1.5-.6 1.7-1.2.2-.6.2-1.1.1-1.2 0-.1-.2-.2-.4-.3Z"/></svg>
</a>
<?php endif; ?>
<?php if ($phone_clean) : ?>
<a class="teacher-single__sticky-icon" href="tel:<?php echo esc_attr($phone_clean); ?>" aria-label="Позвонить">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M22 16.9v3a2 2 0 0 1-2.2 2 19.8 19.8 0 0 1-8.6-3.1 19.5 19.5 0 0 1-6-6A19.8 19.8 0 0 1 2.1 4.2 2 2 0 0 1 4.1 2h3a2 2 0 0 1 2 1.7c.1 1 .4 2 .7 2.9a2 2 0 0 1-.5 2.1L8 10a16 16 0 0 0 6 6l1.3-1.3a2 2 0 0 1 2.1-.5c.9.3 1.9.6 2.9.7a2 2 0 0 1 1.7 2Z"/></svg>
</a>
<?php endif; ?>
</div>
</div>
</main>
<script type="application/ld+json">
<?php echo wp_json_encode(
array(
'@context' => 'https://schema.org',
'@graph' => $schema_graph,
),
JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES
); ?>
</script>
<?php get_footer(); ?>