1044 lines
57 KiB
PHP
1044 lines
57 KiB
PHP
<?php
|
||
/**
|
||
* Личная страница преподавателя (Bento 2026) — конверсионная воронка.
|
||
*
|
||
* Воронка: Meta → Hero (+2 CTA + риск) → Цифры (человек+система) →
|
||
* Дефицит → Сегменты (+4-й под спойлером) → Личная история + «Как проходит
|
||
* занятие» → Кейсы (табы 9/11) → FAQ (формат) → Отзывы → Доверие/лицензия →
|
||
* Другие преподаватели → финальный CTA → Карта. Sticky-CTA на мобильном.
|
||
*
|
||
* Данные — из CF карточки преподавателя (деплой через контент).
|
||
* Общие части переиспользуются: template-parts/reviews, template-parts/teachers-cards,
|
||
* template-parts/contacts (как на главной).
|
||
*
|
||
* @package Dekart
|
||
*/
|
||
|
||
if (! defined('ABSPATH')) {
|
||
exit;
|
||
}
|
||
|
||
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', 'Декарт');
|
||
$phone_clean = $branch_phone ? preg_replace('/[\s\-\–\(\)]/', '', $branch_phone) : '';
|
||
$wa_on = (bool) get_option('branch_messenger_whatsapp_on', 1);
|
||
$wa_url = $wa_on ? get_option('branch_messenger_whatsapp') : '';
|
||
$wa_url = $wa_url ?: ( $phone_clean ? 'https://wa.me/' . $phone_clean : '' );
|
||
|
||
// ─── Профиль преподавателя (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) : '';
|
||
$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;
|
||
}
|
||
|
||
$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 = 'Средний балл учеников';
|
||
}
|
||
$rating_label = 'Рейтинг преподавателя';
|
||
$group_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') ?: '100%';
|
||
$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');
|
||
// Если в поле ссылка (не iframe) — собираем iframe VK/YouTube автоматически. Пусто → блок не выводится.
|
||
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' => 'Подбираем мини-группу 2–6 человек под уровень ребёнка.' ),
|
||
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' => 'В мини-группе 2–6 человек преподаватель видит каждого, но у детей появляется азарт, здоровая конкуренция и живое обсуждение. Стоимость ниже репетитора, а дисциплина выше — пропускать занятия не хочется.',
|
||
);
|
||
$faq_items[] = array(
|
||
'q' => 'Что если ребёнок стесняется заниматься с другими?',
|
||
'a' => 'Начинаем с диагностики и подбираем группу по уровню и темпераменту. Первые занятия преподаватель мягко вовлекает ребёнка — обычно через 2–3 занятия стеснение уходит.',
|
||
);
|
||
} 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'] );
|
||
}
|
||
}
|
||
|
||
// ─── Дни до экзамена (полоса дефицита) ───
|
||
$days_left = '';
|
||
if ($exam_date && preg_match('/^\d{4}-\d{2}-\d{2}$/', $exam_date)) {
|
||
$diff = (int) (( strtotime($exam_date) - current_time('timestamp') ) / DAY_IN_SECONDS);
|
||
if ($diff >= 0) {
|
||
$days_left = (string) $diff;
|
||
}
|
||
}
|
||
|
||
// ─── Микроразметка (Schema.org JSON-LD, единый @graph) ───
|
||
// Данные — только из CF преподавателя и настроек филиала (branch_*/site_*).
|
||
// Пустые свойства в схему не выводятся (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_*), фолбэк — CF theme options (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;
|
||
}
|
||
|
||
// Лицензия (hasCredential) — из настроек филиала
|
||
$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 (преподаватель) ──
|
||
// Каталог программ филиала (единый для всего сайта): название → ссылка.
|
||
// Цена берётся из этого каталога только для микроразметки 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 → name курса (выбор из каталога филиала),
|
||
// teacher_subjects_topics → чипы. URL — из каталога филиала (fallback: legacy url преподавателя);
|
||
// цена — из того же каталога, но используется только микроразметкой Course.offers.
|
||
$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; пусто — сборка из метрик преподавателя) ───
|
||
$results = (array) carbon_get_post_meta($tid, 'teacher_results');
|
||
if (empty($results) || ! is_array($results)) {
|
||
$results = array();
|
||
if ('' !== $school_num) { $results[] = array( 'result_title' => $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);
|
||
}
|
||
|
||
// AggregateRating — только реальные данные. Размещается на Course, а не на Person
|
||
// (свойство aggregateRating невалидно для типа Person в schema.org).
|
||
$course_rating = array();
|
||
if ($rating_num > 0 && $review_count > 0) {
|
||
$course_rating = array(
|
||
'@type' => 'AggregateRating',
|
||
'ratingValue' => number_format($rating_num, 1),
|
||
'bestRating' => '5',
|
||
'ratingCount' => $review_count,
|
||
);
|
||
}
|
||
|
||
// Review — реальные отзывы из CPT «reviews», связанные с преподавателем. Не выдумываем.
|
||
// Размещаются на Course (свойство review невалидно для Person).
|
||
$review_pool = get_posts(array(
|
||
'post_type' => 'reviews',
|
||
'post_status' => 'publish',
|
||
'posts_per_page' => -1,
|
||
'fields' => 'ids',
|
||
'no_found_rows' => true,
|
||
));
|
||
$reviews = array();
|
||
foreach ($review_pool as $rid) {
|
||
$link = carbon_get_post_meta((int) $rid, 'review_teacher');
|
||
if (! is_array($link) || empty($link[0]['id']) || (int) $link[0]['id'] !== $tid) {
|
||
continue;
|
||
}
|
||
$r_author = trim((string) get_the_title((int) $rid));
|
||
$r_body = trim((string) carbon_get_post_meta((int) $rid, 'review_text'));
|
||
$r_star = (int) ( carbon_get_post_meta((int) $rid, 'review_star') ?: 5 );
|
||
|
||
$review = array('@type' => 'Review');
|
||
if ('' !== $r_author) {
|
||
$review['author'] = array('@type' => 'Person', 'name' => $r_author);
|
||
}
|
||
$pub = get_the_date('c', (int) $rid);
|
||
if ($pub) {
|
||
$review['datePublished'] = $pub;
|
||
}
|
||
if ($r_star > 0) {
|
||
$review['reviewRating'] = array(
|
||
'@type' => 'Rating',
|
||
'ratingValue' => (string) $r_star,
|
||
'bestRating' => '5',
|
||
);
|
||
}
|
||
if ('' !== $r_body) {
|
||
$review['reviewBody'] = $r_body;
|
||
}
|
||
$reviews[] = $review;
|
||
if (count($reviews) >= 3) {
|
||
break;
|
||
}
|
||
}
|
||
if (! empty($reviews)) {
|
||
// $reviews переносятся на каждый Course ниже (в блоке сборки Course).
|
||
}
|
||
|
||
// ── Course — по каждому предмету из CF (комбинация предмет + формат мини-группы) ──
|
||
// Валидная структура: Course → hasCourseInstance (CourseInstance) с courseMode/instructor;
|
||
// aggregateRating и review живут на Course (не на Person).
|
||
// Person и Org объявляются один раз (@id), в курсах — только ссылки {"@id": ...}.
|
||
$build_course = function ( $name, $cid, $availability = null, $description = '', $price = '' ) use ( $page_url, $org_id, $person_id, $group_size, $full_name, $course_rating, $reviews, $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 . ' человек',
|
||
),
|
||
);
|
||
// Цена (только микроразметка Course.offers): из каталога программы (per-program) → fallback branch_price.
|
||
$offer_price = ( '' !== (string) $price ) ? $price : $branch_price;
|
||
if ('' !== (string) $offer_price) {
|
||
$course['offers']['price'] = $offer_price;
|
||
$course['offers']['priceCurrency'] = 'RUB';
|
||
}
|
||
if (null !== $availability) {
|
||
$course['offers']['availability'] = $availability;
|
||
}
|
||
if (! empty($course_rating)) {
|
||
$course['aggregateRating'] = $course_rating;
|
||
}
|
||
if (! empty($reviews)) {
|
||
$course['review'] = $reviews;
|
||
}
|
||
return $course;
|
||
};
|
||
|
||
$courses = array();
|
||
if (! empty($subject_names)) {
|
||
foreach ($subject_names as $i => $cn) {
|
||
$availability = ( $seats_left && (int) $seats_left > 0 ) ? 'https://schema.org/LimitedAvailability' : 'https://schema.org/InStock';
|
||
$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 $teachers_page = get_page_by_path('our-teachers'); ?>
|
||
<?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_url) : ?>
|
||
<div class="ds-hero__photo-wrap">
|
||
<div class="ds-hero__photo-frame teacher-single__photo-frame">
|
||
<img class="ds-hero__photo" src="<?php echo esc_url($avatar_url); ?>" alt="<?php echo esc_attr($avatar_alt); ?>" width="600" height="600" loading="eager" decoding="async">
|
||
</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-секции курсов) ───────────────────
|
||
// Каждый курс — отдельная H2-секция «{Предмет} {в городе}» с якорем #course-N
|
||
// (якорь совпадает с @id в микроразметке Course). Цена на странице не выводится.
|
||
?>
|
||
<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']); ?>">Подробнее о программе →</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
|
||
// ─────────────────── СЕГМЕНТЫ «ДЛЯ КОГО» ───────────────────
|
||
?>
|
||
<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 foreach ($segments as $i => $seg) :
|
||
if ($i >= 3) {
|
||
break;
|
||
}
|
||
$s_title = $seg['segment_title'] ?? '';
|
||
$s_text = $seg['segment_text'] ?? '';
|
||
if (! $s_title) {
|
||
continue;
|
||
}
|
||
?>
|
||
<article class="teacher-single__segment-card">
|
||
<span class="teacher-single__segment-icon" aria-hidden="true"><?php echo esc_html(str_pad((string) ( $i + 1 ), 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 foreach ($steps as $i => $step) :
|
||
$st_title = $step['step_title'] ?? '';
|
||
$st_text = $step['step_text'] ?? '';
|
||
if (! $st_title) {
|
||
continue;
|
||
}
|
||
?>
|
||
<li class="teacher-single__timeline-item">
|
||
<span class="teacher-single__timeline-num" aria-hidden="true"><?php echo esc_html($i + 1); ?></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) : ?>
|
||
<button type="button" role="tab" id="case-tab-<?php echo esc_attr($tab); ?>" aria-controls="case-panel-<?php echo esc_attr($tab); ?>" 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) : ?>
|
||
<div role="tabpanel" id="case-panel-<?php echo esc_attr($tab); ?>" aria-labelledby="case-tab-<?php echo esc_attr($tab); ?>" 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
|
||
// ─────────────────── ОБРАЗОВАНИЕ / ПРЕДМЕТЫ / СЕРТИФИКАТЫ ───────────────────
|
||
if ($teacher_subjects || $education || $add_education || carbon_get_post_meta($tid, 'certificates')) :
|
||
$certificates = (array) carbon_get_post_meta($tid, '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 ($teacher_subjects) : ?>
|
||
<div class="teacher-single__edu-col">
|
||
<h3 class="teacher-single__edu-h">Направления</h3>
|
||
<ul class="teacher-single__subject-list">
|
||
<?php foreach ($teacher_subjects as $ts) :
|
||
$s_title = $ts['teacher_subjects_title'] ?? '';
|
||
if (! $s_title) {
|
||
continue;
|
||
}
|
||
?>
|
||
<li>
|
||
<strong><?php echo esc_html($s_title); ?></strong>
|
||
</li>
|
||
<?php endforeach; ?>
|
||
</ul>
|
||
</div>
|
||
<?php endif; ?>
|
||
<?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'] ?? '';
|
||
if (! $c_id) {
|
||
continue;
|
||
}
|
||
$c_url = wp_get_attachment_url($c_id);
|
||
$c_alt = $c_id ? get_post_meta($c_id, '_wp_attachment_image_alt', true) : '';
|
||
if (! $c_url) {
|
||
continue;
|
||
}
|
||
?>
|
||
<figure class="teacher-single__cert">
|
||
<img src="<?php echo esc_url($c_url); ?>" alt="<?php echo esc_attr($c_alt ?: 'Диплом или сертификат — ' . $full_name); ?>" loading="lazy" decoding="async">
|
||
</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
|
||
// ───────────── ОТЗЫВЫ О ПРЕПОДАВАТЕЛЕ (bento-блок «как на главной», 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(); ?>
|