'Помилка безпеки. Оновіть сторінку.']);
}
$title = isset($_POST['st_title']) ? sanitize_text_field($_POST['st_title']) : '';
$content = isset($_POST['st_description']) ? wp_kses_post($_POST['st_description']) : '';
$cat_id = isset($_POST['st_category']) ? intval($_POST['st_category']) : 0;
$password = isset($_POST['st_admin_pass']) ? $_POST['st_admin_pass'] : '';
$secret_key = '1234';
if ($password !== $secret_key) {
wp_send_json_error(['message' => 'Невірний секретний код.']);
}
if (empty($title) || empty($content)) {
wp_send_json_error(['message' => 'Заповніть заголовок та історію.']);
}
$admin = get_user_by('email', get_option('admin_email'));
$author_id = $admin ? $admin->ID : 1;
$post_data = array(
'post_title' => $title,
'post_content' => $content,
'post_status' => 'publish',
'post_author' => $author_id,
'post_type' => 'post',
);
if ($cat_id > 0) {
$post_data['post_category'] = array($cat_id);
}
$post_id = wp_insert_post($post_data, true);
if (!is_wp_error($post_id) && $post_id > 0) {
add_post_meta($post_id, '_frontend_posted', 'yes', true);
$post_url = get_permalink($post_id);
wp_send_json_success([
'message' => 'Ура! Запис успішно опубліковано! 🎉',
'url' => $post_url
]);
} else {
$error_msg = is_wp_error($post_id) ? $post_id->get_error_message() : 'Невідома помилка';
wp_send_json_error(['message' => 'Помилка бази даних: ' . $error_msg]);
}
}
/**
* 1. Обробник AJAX-запиту для авторизації
*/
add_action('wp_ajax_nopriv_st_ajax_login', 'st_ajax_login_handler');
function st_ajax_login_handler() {
// Перевірка безпеки (Nonce)
check_ajax_referer('st-login-nonce', 'security');
$info = array();
$info['user_login'] = sanitize_user($_POST['log']);
$info['user_password'] = $_POST['pwd'];
$info['remember'] = true; // Запам'ятати користувача
// Спроба авторизації через вбудовану функцію WordPress
$user_signon = wp_signon($info, false);
if (is_wp_error($user_signon)) {
wp_send_json_error(array('message' => 'Помилка: Невірний логін або пароль.'));
} else {
wp_set_current_user($user_signon->ID);
wp_send_json_success(array('message' => 'Успішно! Вхід виконано.'));
}
}
/**
* 2. Шорткод [st_login_btn] для виведення кнопки та модального вікна
*/
add_shortcode('st_login_btn', 'st_render_ajax_login_modal');
function st_render_ajax_login_modal() {
// Якщо користувач вже авторизований, кнопку входу не показуємо
if (is_user_logged_in()) {
return '';
}
// Підготовлюємо дані для JS
$ajax_url = admin_url('admin-ajax.php');
$nonce = wp_create_nonce('st-login-nonce');
$html = '
';
return $html;
}
//
add_action('admin_init', function() {
remove_action('admin_init', 'send_frame_options_header', 10);
});
/**
* 2. ОСНОВНОЙ ШОРТКОД [st_edit_tree]
*/
add_shortcode('st_edit_tree', 'st_render_universal_editor_tree');
function st_render_universal_editor_tree() {
// Проверка прав: только для авторизованных пользователей с правами редактирования
if (!is_user_logged_in() || !current_user_can('edit_posts')) {
return '';
}
static $assets_loaded = false;
$html = '';
if (!$assets_loaded) {
$html .= st_get_editor_tree_assets();
$assets_loaded = true;
}
// Главная кнопка вызова интерфейса
$html .= '
';
// Модальное окно 1: Дерево выбора
$html .= '
';
// Сбор данных: Рубрики и их записи
$cats = get_categories(['hide_empty' => true]);
foreach ($cats as $cat) {
$posts = get_posts(['category' => $cat->term_id, 'numberposts' => 100, 'post_status' => 'any']);
if ($posts) {
$html .= '
📂 ' . esc_html($cat->name) . ' (' . count($posts) . ')
';
foreach ($posts as $p) {
// Принудительно задаем параметр Классического редактора
$raw_link = get_edit_post_link($p->ID, 'raw');
$classic_link = add_query_arg('classic-editor', '1', $raw_link);
$html .= '
📄 ' . esc_html($p->post_title) . '';
}
$html .= '
';
}
}
// Сбор данных: Страницы
$pages = get_pages(['number' => 100]);
if ($pages) {
$html .= '
📂 Все страницы
';
foreach ($pages as $pg) {
// Принудительно задаем параметр Классического редактора
$raw_link = get_edit_post_link($pg->ID, 'raw');
$classic_link = add_query_arg('classic-editor', '1', $raw_link);
$html .= '
📑 ' . esc_html($pg->post_title) . '';
}
$html .= '
';
}
$html .= '
';
// Модальное окно 2: Встроенный редактор (Iframe)
$html .= '
';
return $html;
}
/**
* 3. СТИЛИ И СКРИПТЫ
*/
function st_get_editor_tree_assets() {
return '
';
}
//
// Добавляем шорткод [st_vine_buds]
add_shortcode('st_vine_buds', 'st_render_vine_buds_layout');
function st_render_vine_buds_layout() {
static $buds_assets_loaded = false;
$html = '';
if (!$buds_assets_loaded) {
$html .= st_get_vine_buds_assets();
$assets_loaded = true;
}
$html .= '
';
$html .= '
'; // Центральный ствол лозы
// Получаем рубрики
$categories = get_categories(array('hide_empty' => true));
$branch_side = 'left';
foreach ($categories as $index => $cat) {
$posts = get_posts(array(
'category' => $cat->term_id,
'numberposts' => 20, // Ограничение записей
'post_status' => 'publish'
));
if ($posts) {
$branch_side = ($index % 2 === 0) ? 'left' : 'right';
$html .= '
';
$html .= '
';
$html .= '
';
$html .= '
' . esc_html($cat->name) . '
';
// Контейнер для почек и иконки
$html .= '
';
// Скрытый список для модального окна
$hidden_list = '
';
foreach ($posts as $post_index => $p) {
$post_url = esc_url(get_permalink($p->ID));
$post_title = esc_html($p->post_title);
$post_date = get_the_date('d.m.Y', $p->ID);
// Генерация почки (чередование верх/низ)
$is_top = ($post_index % 2 === 0);
$position_class = $is_top ? 'st-bud-top' : 'st-bud-bottom';
$html .= '';
$html .= ' ';
$html .= '';
// Добавление элемента в скрытый список
$hidden_list .= '- ' . $post_date . ' ' . $post_title . '
';
}
$hidden_list .= '
';
// Иконка в конце ветки (кнопка списка)
$html .= '
';
$html .= ' ';
$html .= '
';
// Сохраняем скрытый HTML списка сразу после кнопки для доступа через JS
$html .= '
' . $hidden_list . '
';
$html .= '
'; // Конец st-buds-row
$html .= '
'; // Конец st-branch-content
$html .= '
'; // Конец контейнера ветки
}
}
$html .= '
'; // Конец st-vine-wrapper
// Глобальное модальное окно (одно на всю страницу)
$html .= '
';
return $html;
}
// CSS и JS
function st_get_vine_buds_assets() {
return '
';
}
//кабинет
// =========================================================
// ОСОБИСТИЙ КАБІНЕТ DOCTOR DOBRA (Шорткод: [st_cabinet])
// =========================================================
/**
* 1. ШОРТКОД ЛИЧНОГО КАБИНЕТА
*/
add_shortcode('st_cabinet', 'st_render_personal_cabinet');
function st_render_personal_cabinet() {
static $assets_loaded = false;
$html = '';
if (!$assets_loaded) {
$html .= st_get_cabinet_assets();
$assets_loaded = true;
}
// Если гость — показываем форму Входа / Регистрации
if (!is_user_logged_in()) {
return $html . st_get_auth_forms_html();
}
// Если авторизован — показываем Личный кабинет
$current_user = wp_get_current_user();
$logout_url = wp_logout_url(get_permalink());
$html .= '
';
$html .= ' ';
// Навигация (Табы)
$html .= '
';
$html .= ' ';
$html .= ' ';
$html .= ' ';
$html .= ' ';
$html .= ' ';
$html .= '
';
$html .= '
';
// ТАБ 1: ПРОФИЛЬ
$html .= '
';
$html .= '
';
$html .= '
' . get_avatar($current_user->ID, 80) . '
';
$html .= '
';
$html .= '
' . esc_html($current_user->display_name) . '
';
$html .= '
' . esc_html($current_user->user_email) . '
';
$html .= '
Учасник клубу Doctor Dobra';
$html .= '
';
$html .= '
';
$html .= '
';
// ТАБ 2: АНАМНЕЗ (НОВЫЙ)
$html .= '
';
$html .= '
Медичний Анамнез
';
$html .= '
';
$html .= '
Анкета здоров\'я
';
$html .= '
Будь ласка, заповніть цю анкету перед першою консультацією. Це допоможе лікарю краще підготуватися до вашого візиту та підібрати ефективний план дій.
';
// Сюда можно будет вставить ссылку на Google Форму или форму на сайте
$html .= '
Заповнити анкету';
$html .= '
';
$html .= '
';
// ТАБ 3: ПРОЧИТАННОЕ
$html .= '
';
$html .= '
Історія читання
';
$read_posts = get_user_meta($current_user->ID, '_st_read_posts', true);
if (!empty($read_posts) && is_array($read_posts)) {
$html .= '
';
// Показываем последние 10 прочитанных
$recent_posts = array_slice(array_reverse($read_posts), 0, 10);
foreach ($recent_posts as $post_id) {
if (get_post_status($post_id) === 'publish') {
$html .= '- 📌 ' . get_the_title($post_id) . '
';
}
}
$html .= '
';
} else {
$html .= '
Ви ще не дочитали жодної статті до кінця. Перейдіть у блог!
';
$html .= '
Читати блог';
}
$html .= '
';
// ТАБ 4: КОНСУЛЬТАЦИИ
$html .= '
';
$html .= '
Ваші консультації
';
$html .= '
';
$html .= '
Запис на прийом
';
$html .= '
Щоб записатися на індивідуальну консультацію або супровід, перейдіть до календаря.
';
$html .= '
Обрати час';
$html .= '
';
$html .= '
';
// ТАБ 5: ПОДПИСКА (ГАЙДЫ И МЕНЮ)
$html .= '
';
$html .= '
Підписка
';
$html .= '
';
$html .= '
';
$html .= '
🥑
';
$html .= '
Меню для ШКТ
';
$html .= '
Завантажити PDF';
$html .= '
';
$html .= '
';
$html .= '
📚
';
$html .= '
Закритий клуб
';
$html .= '
Оформити';
$html .= '
';
$html .= '
';
$html .= '
';
$html .= '
'; // Конец контента
$html .= '
'; // Конец враппера
return $html;
}
/**
* 2. ФОРМЫ АВТОРИЗАЦИИ И РЕГИСТРАЦИИ (HTML)
*/
function st_get_auth_forms_html() {
$ajax_url = admin_url('admin-ajax.php');
$nonce = wp_create_nonce('st-auth-nonce');
return '
';
}
/**
* 3. ОБРАБОТЧИКИ AJAX: Вход и Регистрация
*/
add_action('wp_ajax_nopriv_st_cab_ajax_login', 'st_cab_ajax_login_handler');
function st_cab_ajax_login_handler() {
check_ajax_referer('st-auth-nonce', 'security');
$user = wp_signon(['user_login' => $_POST['log'], 'user_password' => $_POST['pwd'], 'remember' => true], false);
if (is_wp_error($user)) {
wp_send_json_error(['message' => 'Невірний логін або пароль.']);
} else {
wp_set_current_user($user->ID);
wp_send_json_success(['message' => 'Успішно! Завантаження кабінету...']);
}
}
add_action('wp_ajax_nopriv_st_cab_ajax_register', 'st_cab_ajax_register_handler');
function st_cab_ajax_register_handler() {
check_ajax_referer('st-auth-nonce', 'security');
$email = sanitize_email($_POST['email']);
$name = sanitize_text_field($_POST['name']);
$password = $_POST['pwd'];
if (email_exists($email) || username_exists($email)) {
wp_send_json_error(['message' => 'Користувач з таким Email вже існує.']);
}
$user_id = wp_create_user($email, $password, $email);
if (is_wp_error($user_id)) {
wp_send_json_error(['message' => $user_id->get_error_message()]);
} else {
wp_update_user(['ID' => $user_id, 'display_name' => $name, 'first_name' => $name]);
wp_signon(['user_login' => $email, 'user_password' => $password, 'remember' => true], false);
wp_send_json_success(['message' => 'Реєстрація успішна! Входимо...']);
}
}
/**
* 4. ОТСЛЕЖИВАНИЕ ПРОЧИТАННЫХ СТАТЕЙ (AJAX)
*/
add_action('wp_footer', 'st_track_read_articles_script');
function st_track_read_articles_script() {
if (is_single() && is_user_logged_in()) {
$post_id = get_the_ID();
$nonce = wp_create_nonce('st-track-nonce');
?>
:root {
--ink-black: #1a1a1a;
--marker-yellow: #ffde59;
--marker-green: #c1ff00;
--marker-blue: #38b6ff;
--bg-paper: #fdfcf8;
--shadow-comic: 4px 4px 0px var(--ink-black);
--border-sketch: 2px solid var(--ink-black);
}
.st-cab-wrapper {
max-width: 800px; margin: 40px auto; background: var(--bg-paper);
border: var(--border-sketch); border-radius: 20px; box-shadow: 8px 8px 0px rgba(0,0,0,0.1);
overflow: hidden; font-family: Georgia, serif;
}
.st-cab-header {
display: flex; justify-content: space-between; align-items: center;
padding: 20px; border-bottom: var(--border-sketch); background: #fff;
}
.st-cab-title { margin: 0; font-size: 24px; font-weight: 800; color: var(--ink-black); }
.st-cab-logout-btn {
display: flex; align-items: center; gap: 8px; color: #ef4444; font-weight: bold;
text-decoration: none; font-family: sans-serif; font-size: 14px;
}
.st-cab-nav { display: flex; overflow-x: auto; border-bottom: var(--border-sketch); background: #f0e9da; }
.st-cab-nav::-webkit-scrollbar { display: none; }
.st-cab-tab {
flex: 1; padding: 15px 10px; border: none; background: none; cursor: pointer;
font-weight: bold; font-family: sans-serif; font-size: 14px; color: #555;
border-right: var(--border-sketch); transition: 0.2s; white-space: nowrap;
}
.st-cab-tab:last-child { border-right: none; }
.st-cab-tab:hover { background: rgba(0,0,0,0.05); }
.st-cab-tab.active { background: #fff; color: var(--ink-black); border-bottom: 3px solid var(--ink-black); }
.st-cab-content { padding: 30px 20px; min-height: 300px; background: #fff; }
.st-cab-pane { display: none; animation: fadeIn 0.4s; }
.st-cab-pane.active { display: block; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
.st-cab-pane h3 { margin-top: 0; margin-bottom: 20px; font-weight: 800; }
.st-profile-card { display: flex; gap: 20px; align-items: center; }
.st-avatar img { border-radius: 50%; border: var(--border-sketch); box-shadow: var(--shadow-comic); }
.st-user-info h3 { margin: 0 0 5px 0; font-size: 22px; }
.st-user-info p { margin: 0 0 10px 0; color: #666; font-family: sans-serif; }
.st-badge { background: var(--marker-yellow); padding: 4px 10px; border-radius: 20px; border: var(--border-sketch); font-size: 12px; font-weight: bold; font-family: sans-serif; }
.st-btn-action {
display: inline-flex; align-items: center; justify-content: center; padding: 10px 20px;
border-radius: 30px; border: var(--border-sketch); box-shadow: var(--shadow-comic);
color: var(--ink-black); text-decoration: none; font-weight: bold; font-family: sans-serif;
transition: 0.2s; cursor: pointer; background: #fff;
}
.st-btn-action:hover { transform: translate(-2px, -2px); box-shadow: 6px 6px 0px var(--ink-black); }
.st-btn-action:active { transform: translate(2px, 2px); box-shadow: 0px 0px 0px var(--ink-black); }
.st-info-card { padding: 20px; border: var(--border-sketch); border-radius: 16px; box-shadow: var(--shadow-comic); background: #fffdf5; }
.st-guides-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 20px; }
.st-guide-card {
border: var(--border-sketch); border-radius: 16px; padding: 20px; text-align: center;
box-shadow: var(--shadow-comic); background: #fff; display: flex; flex-direction: column; align-items: center; gap: 10px;
}
.st-guide-icon { font-size: 40px; }
.st-guide-card h4 { margin: 0; font-family: sans-serif; font-size: 16px; }
.st-locked { opacity: 0.7; background: #f0f0f0; }
.st-read-list { list-style: none; padding: 0; margin: 0; }
.st-read-list li { margin-bottom: 10px; }
.st-read-list a {
display: block; padding: 12px 16px; border: var(--border-sketch); border-radius: 12px;
text-decoration: none; color: var(--ink-black); font-family: sans-serif; font-weight: bold;
transition: 0.2s; background: #fff;
}
.st-read-list a:hover { background: var(--marker-green); transform: translateX(5px); }
.st-empty-state { padding: 30px; text-align: center; border: 2px dashed #ccc; border-radius: 16px; color: #666; font-family: sans-serif; }
.st-auth-wrapper { max-width: 400px; margin: 50px auto; font-family: sans-serif; }
.st-auth-box { background: #fff; border: var(--border-sketch); border-radius: 20px; padding: 25px; box-shadow: 8px 8px 0px rgba(0,0,0,0.1); }
.st-auth-tabs { display: flex; margin-bottom: 20px; border-bottom: 2px solid #eee; }
.st-auth-tab { flex: 1; padding: 10px; border: none; background: none; font-size: 16px; font-weight: bold; cursor: pointer; color: #888; transition: 0.2s; }
.st-auth-tab.active { color: var(--ink-black); border-bottom: 3px solid var(--ink-black); }
.st-input { width: 100%; padding: 12px 15px; margin-bottom: 15px; border: var(--border-sketch); border-radius: 12px; box-sizing: border-box; font-size: 15px; font-family: inherit; }
.st-input:focus { outline: none; border-color: #38b6ff; box-shadow: 0 0 0 3px rgba(56, 182, 255, 0.2); }
.st-auth-msg { margin-top: 15px; padding: 10px; border-radius: 8px; font-size: 14px; text-align: center; display: none; }
.st-auth-msg.success { background: #dcfce7; color: #166534; border: 1px solid #bbf7d0; }
.st-auth-msg.error { background: #fee2e2; color: #991b1b; border: 1px solid #fecaca; }
@media (max-width: 600px) { .st-cab-header { flex-direction: column; gap: 10px; align-items: flex-start; } }
';
}
/**
* Літо 2026 · Меню-комікс
* REST API та таблиці БД для збереження даних користувачів
*/
// Створення таблиць при активації
register_activation_hook(__FILE__, 'summer_menu_create_tables');
function summer_menu_create_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$table_users = $wpdb->prefix . 'summer_users';
$table_checklists = $wpdb->prefix . 'summer_checklists';
$table_completed = $wpdb->prefix . 'summer_completed_days';
$table_notes = $wpdb->prefix . 'summer_notes';
$sql_users = "CREATE TABLE $table_users (
id mediumint(9) NOT NULL AUTO_INCREMENT,
phone varchar(20) NOT NULL UNIQUE,
name varchar(100) DEFAULT '',
token varchar(64) DEFAULT '',
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY phone (phone)
) $charset_collate;";
$sql_checklists = "CREATE TABLE $table_checklists (
id mediumint(9) NOT NULL AUTO_INCREMENT,
user_id mediumint(9) NOT NULL,
week_key varchar(20) NOT NULL,
item_id varchar(255) NOT NULL,
checked tinyint(1) DEFAULT 0,
PRIMARY KEY (id),
UNIQUE KEY user_item (user_id, week_key, item_id)
) $charset_collate;";
$sql_completed = "CREATE TABLE $table_completed (
id mediumint(9) NOT NULL AUTO_INCREMENT,
user_id mediumint(9) NOT NULL,
week_idx varchar(10) NOT NULL,
day_idx int NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY user_day (user_id, week_idx, day_idx)
) $charset_collate;";
$sql_notes = "CREATE TABLE $table_notes (
id mediumint(9) NOT NULL AUTO_INCREMENT,
user_id mediumint(9) NOT NULL,
day_key varchar(255) NOT NULL,
note_text text NOT NULL,
updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY user_day_key (user_id, day_key)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql_users);
dbDelta($sql_checklists);
dbDelta($sql_completed);
dbDelta($sql_notes);
}
// REST API маршрути
add_action('rest_api_init', 'summer_menu_rest_routes');
function summer_menu_rest_routes() {
register_rest_route('summer/v1', '/auth', array(
'methods' => 'POST',
'callback' => 'summer_auth_callback',
'permission_callback' => '__return_true'
));
register_rest_route('summer/v1', '/data', array(
'methods' => 'POST',
'callback' => 'summer_sync_data_callback',
'permission_callback' => 'summer_verify_token'
));
register_rest_route('summer/v1', '/data', array(
'methods' => 'GET',
'callback' => 'summer_get_data_callback',
'permission_callback' => 'summer_verify_token'
));
register_rest_route('summer/v1', '/profile', array(
'methods' => 'POST',
'callback' => 'summer_update_profile_callback',
'permission_callback' => 'summer_verify_token'
));
}
// Авторизація
function summer_auth_callback($request) {
$phone = sanitize_text_field($request->get_param('phone'));
$code = sanitize_text_field($request->get_param('code'));
if ($code !== '2026') {
return new WP_Error('wrong_code', 'Невірний код', array('status' => 403));
}
if (empty($phone)) {
return new WP_Error('no_phone', 'Телефон обов’язковий', array('status' => 400));
}
global $wpdb;
$table_users = $wpdb->prefix . 'summer_users';
$user = $wpdb->get_row($wpdb->prepare("SELECT * FROM $table_users WHERE phone = %s", $phone));
if (!$user) {
$token = bin2hex(random_bytes(32));
$wpdb->insert($table_users, array(
'phone' => $phone,
'token' => $token,
'created_at' => current_time('mysql')
));
$user_id = $wpdb->insert_id;
$name = '';
} else {
$user_id = $user->id;
$token = $user->token;
$name = $user->name;
if (empty($token)) {
$token = bin2hex(random_bytes(32));
$wpdb->update($table_users, array('token' => $token), array('id' => $user_id));
}
}
return rest_ensure_response(array(
'success' => true,
'user_id' => $user_id,
'token' => $token,
'name' => $name
));
}
function summer_verify_token($request) {
$token = $request->get_header('X-Auth-Token');
if (!$token) return false;
global $wpdb;
$table_users = $wpdb->prefix . 'summer_users';
$user = $wpdb->get_row($wpdb->prepare("SELECT id FROM $table_users WHERE token = %s", $token));
if (!$user) return false;
$request->set_param('user_id', $user->id);
return true;
}
function summer_get_data_callback($request) {
$user_id = $request->get_param('user_id');
global $wpdb;
$table_checklists = $wpdb->prefix . 'summer_checklists';
$table_completed = $wpdb->prefix . 'summer_completed_days';
$table_notes = $wpdb->prefix . 'summer_notes';
$checklists = $wpdb->get_results($wpdb->prepare(
"SELECT week_key, item_id, checked FROM $table_checklists WHERE user_id = %d", $user_id
));
$completed = $wpdb->get_results($wpdb->prepare(
"SELECT week_idx, day_idx FROM $table_completed WHERE user_id = %d", $user_id
));
$notes = $wpdb->get_results($wpdb->prepare(
"SELECT day_key, note_text FROM $table_notes WHERE user_id = %d", $user_id
));
$checklist_state = array();
foreach ($checklists as $item) {
$checklist_state[$item->week_key][$item->item_id] = (bool)$item->checked;
}
$completed_state = array();
foreach ($completed as $day) {
$completed_state[$day->week_idx . '_' . $day->day_idx] = true;
}
$notes_state = array();
foreach ($notes as $note) {
$notes_state[$note->day_key] = $note->note_text;
}
return rest_ensure_response(array(
'checklists' => $checklist_state,
'completed' => $completed_state,
'notes' => $notes_state
));
}
function summer_sync_data_callback($request) {
$user_id = $request->get_param('user_id');
$data = $request->get_json_params();
global $wpdb;
$table_checklists = $wpdb->prefix . 'summer_checklists';
$table_completed = $wpdb->prefix . 'summer_completed_days';
$table_notes = $wpdb->prefix . 'summer_notes';
if (isset($data['checklists'])) {
foreach ($data['checklists'] as $week_key => $items) {
foreach ($items as $item_id => $checked) {
$wpdb->replace($table_checklists, array(
'user_id' => $user_id,
'week_key' => $week_key,
'item_id' => $item_id,
'checked' => $checked ? 1 : 0
));
}
}
}
if (isset($data['completed'])) {
$wpdb->delete($table_completed, array('user_id' => $user_id));
foreach ($data['completed'] as $key => $value) {
if (!$value) continue;
list($week_idx, $day_idx) = explode('_', $key);
$wpdb->insert($table_completed, array(
'user_id' => $user_id,
'week_idx' => $week_idx,
'day_idx' => intval($day_idx)
));
}
}
if (isset($data['notes'])) {
foreach ($data['notes'] as $day_key => $note_text) {
if (empty($note_text)) {
$wpdb->delete($table_notes, array('user_id' => $user_id, 'day_key' => $day_key));
} else {
$wpdb->replace($table_notes, array(
'user_id' => $user_id,
'day_key' => $day_key,
'note_text' => $note_text
));
}
}
}
return rest_ensure_response(array('success' => true));
}
function summer_update_profile_callback($request) {
$user_id = $request->get_param('user_id');
$name = sanitize_text_field($request->get_param('name'));
global $wpdb;
$table_users = $wpdb->prefix . 'summer_users';
$wpdb->update($table_users, array('name' => $name), array('id' => $user_id));
return rest_ensure_response(array('success' => true, 'name' => $name));
}