shkola/wp-content/themes/dekart/inc/class-pksh-data.php
2026-07-15 14:15:56 +00:00

504 lines
17 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
/**
* Pksh_Data — централизованная загрузка данных для page-podgotovka-k-shkole.php
*
* Синглтон. Кэширует все carbon_get_post_meta() и get_option() вызовы.
* Каждый template-part вызывает Pksh_Data::instance() -> get_*().
* Повторные вызовы instance() возвращают тот же объект — без дублирования запросов.
*
* @package Dekart
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class Pksh_Data {
private static ?Pksh_Data $instance = null;
private int $post_id;
/** @var array Кэш branch-данных (get_option с fallback) */
private array $branch = [];
/** @var array Кэш page-specific meta */
private array $page = [];
/** @var array|null Кэш complex полей */
private ?array $social = null;
private array $programs = [];
private ?array $compare = null;
private ?array $teachers = null;
private ?array $reviews = null;
private ?array $faq = null;
private ?array $gallery = null;
private function __construct() {
$this->post_id = get_the_ID();
}
/**
* Получить экземпляр (синглтон)
*/
public static function instance(): self {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
// ============================================================
// BRANCH / OPTION DATA (get_option → theme_option → post_meta)
// ============================================================
/**
* Адрес филиала
*/
public function get_address(): string {
$cache_key = 'dekart_branch_address';
$cached = wp_cache_get( $cache_key, 'dekart_branch' );
if ( false !== $cached ) {
return $cached;
}
if ( ! array_key_exists( 'address', $this->branch ) ) {
$this->branch['address'] = get_option( 'branch_address' ) ?:
carbon_get_theme_option( 'site_address' ) ?:
carbon_get_post_meta( $this->post_id, 'contact_address' ) ?:
'';
}
wp_cache_set( $cache_key, $this->branch['address'], 'dekart_branch', DAY_IN_SECONDS );
return $this->branch['address'];
}
/**
* Координаты филиала (для карты)
*/
public function get_coords(): string {
$cache_key = 'dekart_branch_coords';
$cached = wp_cache_get( $cache_key, 'dekart_branch' );
if ( false !== $cached ) {
return $cached;
}
if ( ! array_key_exists( 'coords', $this->branch ) ) {
$this->branch['coords'] = get_option( 'branch_coords' ) ?:
carbon_get_post_meta( $this->post_id, 'contact_location' ) ?:
'';
}
wp_cache_set( $cache_key, $this->branch['coords'], 'dekart_branch', DAY_IN_SECONDS );
return $this->branch['coords'];
}
/**
* Телефон филиала
*/
public function get_phone(): string {
$cache_key = 'dekart_branch_phone';
$cached = wp_cache_get( $cache_key, 'dekart_branch' );
if ( false !== $cached ) {
return $cached;
}
if ( ! array_key_exists( 'phone', $this->branch ) ) {
$this->branch['phone'] = get_option( 'branch_phone' ) ?:
carbon_get_theme_option( 'site_phone' ) ?:
carbon_get_post_meta( $this->post_id, 'contact_tel' ) ?:
'';
}
wp_cache_set( $cache_key, $this->branch['phone'], 'dekart_branch', DAY_IN_SECONDS );
return $this->branch['phone'];
}
/**
* Телефон, очищенный от не-цифровых символов
*/
public function get_phone_clean(): string {
if ( ! array_key_exists( 'phone_clean', $this->branch ) ) {
$this->branch['phone_clean'] = preg_replace( '/[^0-9+]/', '', $this->get_phone() );
}
return $this->branch['phone_clean'];
}
/**
* Email филиала
*/
public function get_email(): string {
$cache_key = 'dekart_branch_email';
$cached = wp_cache_get( $cache_key, 'dekart_branch' );
if ( false !== $cached ) {
return $cached;
}
if ( ! array_key_exists( 'email', $this->branch ) ) {
$this->branch['email'] = get_option( 'branch_email' ) ?:
carbon_get_theme_option( 'site_mail' ) ?:
carbon_get_post_meta( $this->post_id, 'contact_mail' ) ?:
'';
}
wp_cache_set( $cache_key, $this->branch['email'], 'dekart_branch', DAY_IN_SECONDS );
return $this->branch['email'];
}
/**
* Название филиала / организации
*/
public function get_name(): string {
$cache_key = 'dekart_branch_name';
$cached = wp_cache_get( $cache_key, 'dekart_branch' );
if ( false !== $cached ) {
return $cached;
}
if ( ! array_key_exists( 'name', $this->branch ) ) {
$this->branch['name'] = get_option( 'branch_name' ) ?:
carbon_get_theme_option( 'site_name' ) ?:
'Декарт';
}
wp_cache_set( $cache_key, $this->branch['name'], 'dekart_branch', DAY_IN_SECONDS );
return $this->branch['name'];
}
/**
* Город с предлогом (например "в Щёлково")
*/
public function get_city_prep(): string {
$cache_key = 'dekart_branch_city_prep';
$cached = wp_cache_get( $cache_key, 'dekart_branch' );
if ( false !== $cached ) {
return $cached;
}
if ( ! array_key_exists( 'city_prep', $this->branch ) ) {
$this->branch['city_prep'] = get_option( 'branch_city_prep', 'в Щёлково' );
}
wp_cache_set( $cache_key, $this->branch['city_prep'], 'dekart_branch', DAY_IN_SECONDS );
return $this->branch['city_prep'];
}
/**
* Город без предлога (например "Щёлково")
*/
public function get_city_clean(): string {
if ( ! array_key_exists( 'city_clean', $this->branch ) ) {
$this->branch['city_clean'] = str_replace( array( 'в ', 'В ' ), '', $this->get_city_prep() );
}
return $this->branch['city_clean'];
}
/**
* Количество отзывов на внешних площадках
*/
public function get_ext_review_count(): string {
$cache_key = 'dekart_branch_ext_review_count';
$cached = wp_cache_get( $cache_key, 'dekart_branch' );
if ( false !== $cached ) {
return $cached;
}
if ( ! array_key_exists( 'ext_review_count', $this->branch ) ) {
$this->branch['ext_review_count'] = get_option( 'branch_ext_review_count', '247' );
}
wp_cache_set( $cache_key, $this->branch['ext_review_count'], 'dekart_branch', DAY_IN_SECONDS );
return $this->branch['ext_review_count'];
}
/**
* Социальные сети (из branch_social option или CF)
*/
public function get_social_links(): array {
$cache_key = 'dekart_branch_social';
$cached = wp_cache_get( $cache_key, 'dekart_branch' );
if ( false !== $cached ) {
return $cached;
}
if ( ! array_key_exists( 'social', $this->branch ) ) {
$raw = get_option( 'branch_social' ) ?:
carbon_get_post_meta( $this->post_id, 'social_media' ) ?:
[];
$this->branch['social'] = is_array( $raw ) ? $raw : [];
}
wp_cache_set( $cache_key, $this->branch['social'], 'dekart_branch', DAY_IN_SECONDS );
return $this->branch['social'];
}
/**
* Логистика — пешком от ТЦ (branch_logistics_walk)
*/
public function get_logistics_walk(): string {
if ( ! array_key_exists( 'logistics_walk', $this->branch ) ) {
$this->branch['logistics_walk'] = get_option( 'branch_logistics_walk', '5 минут пешком от ТЦ «Глобус»' );
}
return $this->branch['logistics_walk'];
}
/**
* Логистика — парковка (branch_logistics_parking)
*/
public function get_logistics_parking(): string {
if ( ! array_key_exists( 'logistics_parking', $this->branch ) ) {
$this->branch['logistics_parking'] = get_option( 'branch_logistics_parking', 'Есть бесплатная парковка у входа' );
}
return $this->branch['logistics_parking'];
}
/**
* Логистика — соседние школы/сад (branch_logistics_schools)
*/
public function get_logistics_nearby(): string {
if ( ! array_key_exists( 'logistics_nearby', $this->branch ) ) {
$this->branch['logistics_nearby'] = get_option( 'branch_logistics_schools', 'Рядом со школами №9 и №12, детским садом №15' );
}
return $this->branch['logistics_nearby'];
}
// ============================================================
// HERO / BANNER
// ============================================================
/**
* ID изображения баннера (hero)
*/
public function get_banner_image_id(): int {
if ( ! array_key_exists( 'banner_image_id', $this->page ) ) {
$this->page['banner_image_id'] = (int) carbon_get_post_meta( $this->post_id, 'banner_image' );
}
return $this->page['banner_image_id'];
}
/**
* H1 заголовок hero-секции
*/
public function get_h1(): string {
if ( ! array_key_exists( 'h1', $this->page ) ) {
$this->page['h1'] = carbon_get_post_meta( $this->post_id, 'banner_h1' ) ?:
'Подготовка к школе в Щёлково';
}
return $this->page['h1'];
}
/**
* Подзаголовок hero
*/
public function get_subtitle(): string {
if ( ! array_key_exists( 'subtitle', $this->page ) ) {
$this->page['subtitle'] = carbon_get_post_meta( $this->post_id, 'banner_subtitle' ) ?:
'Первое занятие — бесплатно. Ребёнок научится читать, считать и писать в игровой форме. Группы до 10 человек.';
}
return $this->page['subtitle'];
}
/**
* Ссылка для * в подзаголовке hero
*/
public function get_subtitle_footnote_link(): string {
if ( ! array_key_exists( 'subtitle_footnote_link', $this->page ) ) {
$this->page['subtitle_footnote_link'] = carbon_get_post_meta( $this->post_id, 'banner_subtitle_footnote_link' ) ?: '';
}
return $this->page['subtitle_footnote_link'];
}
// ============================================================
// SOCIAL COUNTERS (complex)
// ============================================================
/**
* Массив social counters (complex field pksh_social_counters)
* @return array[]
*/
public function get_social_counters(): array {
if ( null === $this->social ) {
$raw = carbon_get_post_meta( $this->post_id, 'pksh_social_counters' );
$this->social = is_array( $raw ) ? $raw : [];
}
return $this->social;
}
/**
* Иконки для social counters (порядок соответствует полю)
*/
public static function social_icons(): array {
return array( '🎓', '📅', '⭐', '👩‍🏫' );
}
// ============================================================
// PROGRAMS
// ============================================================
/**
* Данные базовой программы
* @return array{name: string, subname: string, schedule: string, price_sub: string, price_single: string, price_razov: string, urgency: string}
*/
public function get_base_program(): array {
if ( ! array_key_exists( 'base', $this->programs ) ) {
$this->programs['base'] = array(
'name' => carbon_get_post_meta( $this->post_id, 'pksh_prog_base_name' ) ?: 'Уверенный старт',
'subname' => carbon_get_post_meta( $this->post_id, 'pksh_prog_base_subname' ) ?: '2 раза в неделю — комфортный темп без перегрузки',
'schedule' => carbon_get_post_meta( $this->post_id, 'pksh_prog_base_schedule' ) ?: 'вт, чт — 18:0019:30',
'price_sub' => carbon_get_post_meta( $this->post_id, 'pksh_prog_base_price_sub' ) ?: '7 500 ₽',
'price_single' => carbon_get_post_meta( $this->post_id, 'pksh_prog_base_price_single' ) ?: '1 000 ₽',
'price_razov' => carbon_get_post_meta( $this->post_id, 'pksh_prog_base_price_razov' ) ?: '',
'urgency' => carbon_get_post_meta( $this->post_id, 'pksh_prog_base_urgency' ) ?: 'Осталось 2 места в группе',
);
}
return $this->programs['base'];
}
/**
* Данные премиум-программы
* @return array{name: string, subname: string, schedule: string, price_sub: string, price_single: string, price_razov: string, urgency: string}
*/
public function get_premium_program(): array {
if ( ! array_key_exists( 'prem', $this->programs ) ) {
$this->programs['prem'] = array(
'name' => carbon_get_post_meta( $this->post_id, 'pksh_prog_prem_name' ) ?: 'Результат за 3 месяца',
'subname' => carbon_get_post_meta( $this->post_id, 'pksh_prog_prem_subname' ) ?: '3 раза в неделю — быстрый прогресс',
'schedule' => carbon_get_post_meta( $this->post_id, 'pksh_prog_prem_schedule' ) ?: 'пн, ср, пт — 16:3018:00',
'price_sub' => carbon_get_post_meta( $this->post_id, 'pksh_prog_prem_price_sub' ) ?: '10 500 ₽',
'price_single' => carbon_get_post_meta( $this->post_id, 'pksh_prog_prem_price_single' ) ?: '1 500 ₽',
'price_razov' => carbon_get_post_meta( $this->post_id, 'pksh_prog_prem_price_razov' ) ?: '',
'urgency' => carbon_get_post_meta( $this->post_id, 'pksh_prog_prem_urgency' ) ?: 'Осталось 3 места в группе',
);
}
return $this->programs['prem'];
}
// ============================================================
// COMPARE TABLE (complex)
// ============================================================
/**
* Строки таблицы сравнения
* @return array[]
*/
public function get_compare_rows(): array {
if ( null === $this->compare ) {
$raw = carbon_get_post_meta( $this->post_id, 'pksh_compare_rows' );
$this->compare = is_array( $raw ) ? $raw : [];
}
return $this->compare;
}
/**
* Сноска под таблицей сравнения
*/
public function get_compare_footnote(): string {
if ( ! array_key_exists( 'footnote', $this->page ) ) {
$this->page['footnote'] = carbon_get_post_meta( $this->post_id, 'pksh_compare_footnote' ) ?: '';
}
return $this->page['footnote'];
}
// ============================================================
// TEACHERS (complex)
// ============================================================
/**
* Массив преподавателей (complex field pksh_teachers)
* @return array[]
*/
public function get_teachers(): array {
if ( null === $this->teachers ) {
$raw = carbon_get_post_meta( $this->post_id, 'pksh_teachers' );
$this->teachers = is_array( $raw ) ? $raw : [];
}
return $this->teachers;
}
// ============================================================
// REVIEWS (complex)
// ============================================================
/**
* Массив отзывов (complex field pksh_reviews_list)
* @return array[]
*/
public function get_reviews(): array {
if ( null === $this->reviews ) {
$raw = carbon_get_post_meta( $this->post_id, 'pksh_reviews_list' );
$this->reviews = is_array( $raw ) ? $raw : [];
}
return $this->reviews;
}
// ============================================================
// FAQ (complex)
// ============================================================
/**
* Массив FAQ (complex field pksh_faq_items)
* @return array[]
*/
public function get_faq_items(): array {
if ( null === $this->faq ) {
$raw = carbon_get_post_meta( $this->post_id, 'pksh_faq_items' );
$this->faq = is_array( $raw ) ? $raw : [];
}
return $this->faq;
}
// ============================================================
// GALLERY (complex)
// ============================================================
/**
* Массив фотографий (complex field pksh_gallery)
* @return array[]
*/
public function get_gallery(): array {
if ( null === $this->gallery ) {
$raw = carbon_get_post_meta( $this->post_id, 'pksh_gallery' );
$this->gallery = is_array( $raw ) ? $raw : [];
}
return $this->gallery;
}
// ============================================================
// HONEST TIMER (shared helper)
// ============================================================
/**
* Timestamp честного дедлайна
*/
public function get_honest_deadline(): int {
if ( ! array_key_exists( 'deadline', $this->page ) ) {
$this->page['deadline'] = function_exists( 'dekart_get_honest_deadline' )
? (int) dekart_get_honest_deadline()
: 0;
}
return $this->page['deadline'];
}
/**
* Вывести HTML честного таймера + inline JS.
* Используется в #cta-test и #final-cta.
*
* @param string $label Текст над таймером.
*/
public static function render_honest_timer( string $label = 'Цены действуют до конца месяца:' ): void {
$ts = self::instance()->get_honest_deadline();
if ( $ts <= 0 ) {
return;
}
?>
<div class="honest-timer" data-deadline="<?php echo (int) $ts; ?>">
<span class="honest-timer__label"><?php echo esc_html( $label ); ?></span>
<div class="honest-timer__digits">
<span class="honest-timer__unit">
<span class="honest-timer__num" data-timer="d">00</span>
<span class="honest-timer__unit-label">дн</span>
</span>
<span class="honest-timer__sep">:</span>
<span class="honest-timer__unit">
<span class="honest-timer__num" data-timer="h">00</span>
<span class="honest-timer__unit-label">ч</span>
</span>
<span class="honest-timer__sep">:</span>
<span class="honest-timer__unit">
<span class="honest-timer__num" data-timer="m">00</span>
<span class="honest-timer__unit-label">мин</span>
</span>
<span class="honest-timer__sep">:</span>
<span class="honest-timer__unit">
<span class="honest-timer__num" data-timer="s">00</span>
<span class="honest-timer__unit-label">сек</span>
</span>
</div>
</div>
<?php
}
}