$timestamp, 'method' => $_SERVER['REQUEST_METHOD'] ?? 'UNKNOWN', 'query' => $_GET ?? [], 'post' => $_POST ?? [], 'raw_body' => $rawInput, 'decoded_body' => $decoded, 'headers' => $this->getRequestHeaders() ]; $logEntry = '[' . $timestamp . '] Platina callback: ' . json_encode($logData, JSON_UNESCAPED_UNICODE) . PHP_EOL; file_put_contents($logFile, $logEntry, FILE_APPEND | LOCK_EX); if ($_SERVER['REQUEST_METHOD'] === 'POST' && is_array($decoded) && isset($decoded['invoice_id'])) { $invoiceId = $decoded['invoice_id']; $status = $decoded['status'] ?? null; $amount = isset($decoded['amount']) ? floatval($decoded['amount']) : 0.0; // Логируем получение callback if (function_exists('app_log')) { app_log('payments', 'platina_callback_received', [ 'invoice_id' => $invoiceId, 'status' => $status, 'amount' => $amount ], 'info'); } $this->loadModel('account'); $invoiceRows = $this->model->db->row( "SELECT * FROM platina_invoices WHERE invoice_id = :invoice_id", ['invoice_id' => $invoiceId] ); if ($invoiceRows && isset($invoiceRows[0])) { $invoice = $invoiceRows[0]; if ($amount <= 0) { $amount = floatval($invoice['callback_amount'] ?? $invoice['amount']); } $updateData = [ 'status' => $status, 'callback_amount' => $amount, 'callback_at' => date('Y-m-d H:i:s') ]; if ($invoice['callback_status'] === 'processed') { // Логируем повторный callback для уже обработанного платежа if (function_exists('app_log')) { app_log('payments', 'platina_callback_duplicate', [ 'invoice_id' => $invoiceId, 'user_id' => $invoice['user_id'] ?? null, 'status' => $status ], 'warning'); } $updateData['callback_status'] = 'processed'; $this->model->updatePlatinaInvoice($invoiceId, $updateData); } else { if (in_array($status, ['payed', 'partial_payment'])) { $result = $this->model->processPlatinaPayment($invoice, $amount); if ($result['success']) { $updateData['callback_status'] = 'processed'; } else { $updateData['callback_status'] = 'processing_error'; file_put_contents($logFile, '[' . date('Y-m-d H:i:s') . "] Platina processing error | Invoice {$invoiceId}" . PHP_EOL, FILE_APPEND | LOCK_EX); // Логирование ошибки уже в processPlatinaPayment() } } else { $updateData['callback_status'] = $status; // Логируем другие статусы if (function_exists('app_log')) { app_log('payments', 'platina_callback_status', [ 'invoice_id' => $invoiceId, 'user_id' => $invoice['user_id'] ?? null, 'status' => $status, 'amount' => $amount ], 'info'); } } $this->model->updatePlatinaInvoice($invoiceId, $updateData); } } else { // Логируем callback для несуществующего инвойса if (function_exists('app_log')) { app_log('payments', 'platina_callback_invoice_not_found', [ 'invoice_id' => $invoiceId, 'status' => $status, 'amount' => $amount ], 'error'); } } } header('Content-Type: application/json'); echo json_encode(['status' => 'ok']); die; } public function ajax_form() { $this->loadModel('front'); switch($_POST['action']){ case "contact_form": $captcha=$_POST['g-recaptcha-response']; $response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=6LcKprYpAAAAADsNs2FfXYNI1VtvNpTox_BH4tvc&response=".$captcha."&remoteip=".$_SERVER['REMOTE_ADDR']); $g_response = json_decode($response, true); if($g_response['success']){ //if(1 == 1){ $admin_email = "xotabch1997@gmail.com"; $admin_email = "admin.kiev-girls.info@proton.me"; $headers = "From: KievGirls". "\r\n"; $message = "Имя: {$_POST['name']}\nEmail: {$_POST['email']}\n"; if(isset($_POST['message'])){ $message .= "Сообщение: {$_POST['message']}"; } mail($admin_email, $_POST["subject"], $message, $headers); echo get_trans('contact_form'); }else{ echo get_trans('recaptcha'); } break; case "addFavorite": $girlID = $_POST['id']; $turn = $_POST['turn']; if (isset($_COOKIE['favoriteGirls']) && !empty($_COOKIE['favoriteGirls'])) { $likedGirls = explode(',', $_COOKIE['favoriteGirls']); } else { $likedGirls = []; } if ($turn) { if (!in_array($girlID, $likedGirls)) { $likedGirls[] = $girlID; } } else { if (($key = array_search($girlID, $likedGirls)) !== false) { unset($likedGirls[$key]); } } setcookie('favoriteGirls', implode(',', $likedGirls), time() + 365 * 24 * 3600, "/"); echo json_encode(['status' => true]); die; case "click_ad": $ad_id = intval($_POST['ad_id']); if (is_int($ad_id)) { $this->model->register_ad_view($ad_id); } $this->loadModel('front'); $data['ad'] = $this->model->getAdByID($ad_id); $data['title'] = $data['ad']['title']; $data['meta_description'] = $string = strip_tags($data['ad']['description']); $string = substr($string, 0, 200); $string = rtrim($string, "!,.-"); $string = substr($string, 0, strrpos($string, ' ')); $arr['data']['meta_description'] = ""; $data['SEOh1'] = $data['ad']['title']; $data['filter_page_type'] = 'ad'; $this->current_page('ad', ''); extract($data); require 'application/views/front/work_ad.php'; die; } } public function login() { $errors = array(); if(isset($_SESSION['is_auth']) && $_SESSION['is_auth'] == true){ switch($_SESSION['access_level']){ case '7': $link = '/programmer/panel/'; break; case '3': $link = '/seo/panel/'; break; case '2': $link = '/admin/users/'; break; case '0': $link = '/user/panel/'; break; default: $link = '/user/panel/'; break; } header("Location: {$link}"); } if(issetPost()){ switch($_POST['action']){ case 'login': // Проверка каптчи только при первом запросе (когда не требуется 2FA код) $need2FA = isset($_POST['twofa_code']) && !empty($_POST['twofa_code']); $captchaValid = true; if(!$need2FA){ // Временное отключение проверки reCAPTCHA при логине /* // Проверяем каптчу только при первом запросе $captcha = $_POST['g-recaptcha-response'] ?? ''; $response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=6LcKprYpAAAAADsNs2FfXYNI1VtvNpTox_BH4tvc&response=".$captcha."&remoteip=".$_SERVER['REMOTE_ADDR']); $g_response = json_decode($response, true); $captchaValid = $g_response['success'] ?? false; if(!$captchaValid){ // Логируем ошибку каптчи $this->logger->error('auth', 'captcha_failed', [ 'email' => $_POST['email'] ?? '', 'error_code' => $g_response['error-codes'][0] ?? 'unknown' ]); switch($g_response['error-codes'][0] ?? ''){ case "invalid-input-response": $errors[] = 'Вы не прошли проверку recaptcha!'; break; default: $errors[] = 'Ошибка проверки recaptcha. Попробуйте еще раз.'; break; } } */ } if($captchaValid){ $this->loadModel('front'); // Проверяем блокировку перед попыткой входа $ipAddress = $this->getUserIp(); $email = $_POST['email'] ?? ''; if ($this->model->isBlocked($ipAddress, $email)) { $blockInfo = $this->model->getBlockInfo($ipAddress, $email); if ($blockInfo['blocked']) { // Логируем попытку входа с заблокированного IP/email $this->logger->warning('auth', 'login_blocked', [ 'email' => $email, 'ip' => $ipAddress, 'remaining_minutes' => $blockInfo['remaining_minutes'] ]); $errors[] = "Слишком много неудачных попыток входа. Попробуйте снова через " . $blockInfo['remaining_minutes'] . " минут."; } } else { $result = $this->model->auth_user(); switch($result){ case 'success': // Логируем успешный вход $this->logger->success('auth', 'login', [ 'user_id' => $_SESSION['user_id'] ?? null, 'access_level' => $_SESSION['access_level'] ?? null, 'remember_me' => isset($_POST['remember_me']) ]); switch($_SESSION['access_level']){ case '7': $link = '/programmer/panel/'; break; case '3': $link = '/seo/panel/'; break; case '2': $link = '/admin/users/'; break; case '0': $link = '/user/panel/'; break; default: $link = '/user/panel/'; break; } header("Location: {$link}"); break; case 'activation': // Логируем попытку входа в неактивированный аккаунт $this->logger->warning('auth', 'login_not_activated', [ 'email' => $email ]); $errors[] = "Пожалуйста, активируйте Ваш аккаунт! На Ваш email было отправленно письмо."; break; case 'blocked': $blockInfo = $this->model->getBlockInfo($ipAddress, $email); if ($blockInfo['blocked']) { // Логируем блокировку после неудачных попыток $this->logger->warning('auth', 'login_blocked', [ 'email' => $email, 'ip' => $ipAddress, 'remaining_minutes' => $blockInfo['remaining_minutes'] ]); $errors[] = "Слишком много неудачных попыток входа. Попробуйте снова через " . $blockInfo['remaining_minutes'] . " минут."; } break; case 'need_2fa': // Логируем запрос 2FA кода $this->logger->info('auth', '2fa_code_requested', [ 'email' => $_POST['email'] ]); $data['need_2fa'] = true; $data['email'] = $_POST['email']; $data['password'] = $_POST['password']; if (isset($_POST['remember_me'])) { $data['remember_me'] = true; } $data['success'][] = "Код двухфакторной аутентификации отправлен в ваш Telegram. Введите код для завершения входа."; break; case 'invalid_2fa': // Логируем неверный 2FA код $this->logger->error('auth', '2fa_code_invalid', [ 'email' => $_POST['email'] ]); $errors[] = "Неверный код двухфакторной аутентификации!"; $data['need_2fa'] = true; $data['email'] = $_POST['email']; $data['password'] = $_POST['password']; if (isset($_POST['remember_me'])) { $data['remember_me'] = true; } break; case 'fail': // Логирование неудачной попытки входа уже в auth_user() $errors[] = "Неправильный email или пароль!"; break; } } } break; default: die; } } if(count($errors) > 0){ $data['errors'] = $errors; } $data['title'] = get_trans('login'); $data['meta_description'] = get_trans('login'); $data['SEOh1'] = get_trans('login'); $data['seo_text'] = ''; $this->current_page('page', '4'); $this->view->render('front/login', $data, false); } public function registration() { $this->loadModel('front'); $data['activation'] = false; if(isset($_SESSION['is_auth']) && $_SESSION['is_auth'] == true){ switch($_SESSION['access_level']){ case '7': $link = '/programmer/panel/'; break; case '3': $link = '/seo/panel/'; break; case '2': $link = '/admin/users/'; break; case '0': $link = '/user/panel/'; break; default: $link = '/user/panel/'; break; } header("Location: {$link}"); } if(issetPost()){ $errors = $this->validateFormRegister(); $captcha=$_POST['g-recaptcha-response']; $response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=6LcKprYpAAAAADsNs2FfXYNI1VtvNpTox_BH4tvc&response=".$captcha."&remoteip=".$_SERVER['REMOTE_ADDR']); $g_response = json_decode($response, true); if($g_response['success']){ //if(1 == 1){ if(count($errors) == 0){ $this->loadModel('front'); $result = $this->model->registerUser(); // Логируем регистрацию if (isset($result['status']) && $result['status'] === 'success') { $this->logger->success('auth', 'register', [ 'email' => $_POST['email'] ?? '', 'name' => $_POST['name'] ?? '' ]); } else { $this->logger->error('auth', 'register_failed', [ 'email' => $_POST['email'] ?? '', 'error' => $result['message'] ?? 'unknown' ]); } //$data['success'][] = 'На Ваш email отправленно письмо для подтверждения email! Пожалуйста активируйте аккаунт.'; $data['success'][] = 'Вы успешно зарегистрированы! Для активации вашей учётной записи Вам необходимо подтвердить адрес электронной почты.'; } else { // Логируем ошибки валидации при регистрации $this->logger->error('auth', 'register_validation_failed', [ 'email' => $_POST['email'] ?? '', 'errors' => $errors ]); } }else{ // Логируем ошибку каптчи при регистрации $this->logger->error('auth', 'register_captcha_failed', [ 'email' => $_POST['email'] ?? '', 'error_code' => $g_response['error-codes'][0] ?? 'unknown' ]); switch($g_response['error-codes'][0]){ case "invalid-input-response": $errors[] = 'Вы не прошли проверку recaptcha!'; break; } } $data['errors'] = $errors; } if(isset($_GET['action']) && $_GET['action'] == 'activation'){ $success = array(); $errors = array(); $result = $this->model->activation_user(); switch($result){ case 'notfound': $errors[] = "Такой email не найден!"; break; case 'notcode': $errors[] = 'Невверный код активации! Пожалуйста свяжитесь с администратором для решения проблемы.'; break; case 'activated': $success[] = 'Ваш аккаунт уже активирован! Можете войти используя свой email и пароль.'; break; case 'success': $success[] = 'Ваш аккаунт активирован! Можете войти используя свой email и пароль.'; break; } if(count($errors) > 0){ $data['errors'] = $errors; } if(count($success) > 0){ $data['success'] = $success; } $data['activation'] = true; } $data['title'] = get_trans('register'); $data['meta_description'] = get_trans('register'); $data['SEOh1'] = get_trans('register'); $data['seo_text'] = ''; $this->current_page('page', '6'); $this->view->render('front/registration', $data, false); } public function recovery_password() { $this->loadModel('front'); /* if(isset($_SESSION['is_auth']) && $_SESSION['is_auth'] == true){ switch($_SESSION['access_level']){ case '7': $link = '/programmer/panel/'; break; case '2': $link = '/admin/users/'; break; case '0': $link = '/user/panel/'; break; default: $link = '/user/panel/'; break; } header("Location: {$link}"); } */ if(issetPost()){ switch($_POST['action']){ case 'recovery': $errors = array(); $captcha=$_POST['g-recaptcha-response']; $response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=6LcKprYpAAAAADsNs2FfXYNI1VtvNpTox_BH4tvc&response=".$captcha."&remoteip=".$_SERVER['REMOTE_ADDR']); $g_response = json_decode($response, true); if($g_response['success']){ //if(1 == 1){ if(count($errors) == 0){ $this->loadModel('front'); $tmp = $this->model->recovery_password(); // Логируем запрос восстановления пароля if (isset($tmp['status'])) { if ($tmp['status'] === 'success') { $this->logger->info('auth', 'password_recovery_requested', [ 'email' => $_POST['email'] ?? '' ]); } else { $this->logger->error('auth', 'password_recovery_failed', [ 'email' => $_POST['email'] ?? '', 'reason' => $tmp['message'] ?? 'unknown' ]); } } $data['success'][] = 'На Ваш email отправлено письмо c инструкцией!'; } else { // Логируем ошибки валидации при восстановлении $this->logger->error('auth', 'password_recovery_validation_failed', [ 'email' => $_POST['email'] ?? '', 'errors' => $errors ]); } }else{ // Логируем ошибку каптчи при восстановлении $this->logger->error('auth', 'password_recovery_captcha_failed', [ 'email' => $_POST['email'] ?? '', 'error_code' => $g_response['error-codes'][0] ?? 'unknown' ]); switch($g_response['error-codes'][0]){ case "invalid-input-response": $errors[] = 'Вы не прошли проверку recaptcha!'; break; } } $data['errors'] = $errors; break; case 'change_password': $errors = $this->validateFormRecovery(); $captcha=$_POST['g-recaptcha-response']; $response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=6LcKprYpAAAAADsNs2FfXYNI1VtvNpTox_BH4tvc&response=".$captcha."&remoteip=".$_SERVER['REMOTE_ADDR']); $g_response = json_decode($response, true); if(count($errors) == 0){ if($g_response['success']){ //if(1 == 1){ if(count($errors) == 0){ $this->loadModel('front'); $tmp = $this->model->change_password(); // Логирование уже в модели change_password() if($tmp && isset($tmp['status']) && $tmp['status'] === 'success'){ $data['success'][] = 'Ваш пароль успешно изменен! Теперь Вы можете войти в аккаунт с новым паролем.'; }else{ $errors[] = 'Такой запрос не найден, либо срок его действия уже истек! Попробуйте сбросить пароль заново.'; } } }else{ switch($g_response['error-codes'][0]){ case "invalid-input-response": $errors[] = 'Вы не прошли проверку recaptcha!'; break; } } } $data['errors'] = $errors; break; } } $data['title'] = get_trans('recovery_password'); $data['meta_description'] = get_trans('recovery_password'); $data['SEOh1'] = get_trans('recovery_password'); $data['seo_text'] = ''; $this->current_page('page', '6'); $this->view->render('front/recovery', $data, false); } public function validateFormRegister() { $errors = array(); if($_POST['name'] == ""){ $errors[] = 'Поле имя не может быть пустым!'; } if(!preg_match("/[0-9a-z]+@[a-z]/", $_POST['email']) || strpos($_POST['email'], ' ') !== false){ $errors[] = 'Некоректный email.'; } $this->loadModel('user'); if($this->model->checkEmail($_POST['email'])){ $errors[] = 'Этот email уже занят.'; } if($_POST['password'] != ""){ if(!preg_match('/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[0-9a-zA-Z]{8,24}$/', $_POST['password'])){ $errors[] = 'Пароль слишком слабый. Используйте латинские буквы большого и маленького регистра, а также цифры. Длина длинее 7 символов. Не используйте спец. символы, такие как ".,&" и прочие.'; } if(strpos($_POST['password'],$_POST['retry_password']) === false){ $errors[] = 'Пароли не совпадают!'; } } return $errors; } public function validateFormRecovery() { $errors = array(); if($_POST['password'] != ""){ if(!preg_match('/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[0-9a-zA-Z]{8,24}$/', $_POST['password'])){ $errors[] = 'Пароль слишком слабый. Используйте латинские буквы большого и маленького регистра, а также цифры. Длина длинее 7 символов. Не используйте спец. символы, такие как ".,&" и прочие.'; } if(strpos($_POST['password'],$_POST['retry_password']) === false){ $errors[] = 'Пароли не совпадают!'; } } return $errors; } public function ajax_anket() { $this->loadModel('front'); $temp = $this->model->getAjaxGirl(); $is_ajax = true; if($_POST['offset_girl'] == 0){ echo '
'; } $ix = (int)$_POST['offset_girl']; foreach($temp['girls'] as $girl){ $ix++; $girl = new Girl($girl); require 'application/views/partials/individual.php'; } if($temp['btn']){ $btn = '
'.get_trans('show_more').'
'; }else{ $btn = ''; } if($_POST['offset_girl'] == 0){ echo '
'; } } public function favorite() { $this->loadModel('front'); $data['title'] = get_trans("favorite"); $data['breadcrumb'] = get_trans("favorite"); $data['SEOh1'] = get_trans("favorite"); $data['SEOtext'] = ""; $data['category_link'] = "favorite"; $temp = $this->model->getFavoriteGirls(); $data['girls'] = $temp['girls']; $data['pages'] = $temp['pages']; $data['filter_page_type'] = 'favorite'; $this->current_page('favorite', ''); $this->view->render('front/category', $data, false); } public function home() { $this->loadModel('front'); $data['page'] = $this->model->getHomePage(); $meta = (!empty($data['page']) && is_array($data['page'])) ? get_page_meta_data($data['page']) : ['data' => ['title' => '', 'meta_description' => '', 'SEOh1' => '', 'SEOtext' => '']]; $data = array_merge($data, $meta['data'] ?? []); $temp = $this->model->getHomeGirls(); $data['girls'] = $temp['girls']; $data['pages'] = $temp['pages']; $data['filter_page_type'] = 'home'; $this->current_page('rost', ''); $view_path = (isset($_SESSION['is_amp']) && $_SESSION['is_amp']) ? 'front/amp/home' : 'front/home'; $use_layout = !empty($_SESSION['is_amp']); $this->view->render($view_path, $data, $use_layout); } public function page() { $this->loadModel('front'); switch($this->slug){ case "contacts": $data['page'] = $this->model->getPageSlug($this->slug); $this->current_page('page', $data['page']['id']); extract(get_page_meta_data($data['page'])); $this->view->render('front/contacts', $data, false); break; default: $data['page'] = $this->model->getPageSlug($this->slug); $this->current_page('page', $data['page']['id']); extract(get_page_meta_data($data['page'])); $data['page_slug'] = $this->slug; $this->view->render('front/page', $data, false); break; } } public function work() { $this->loadModel('front'); if($_SESSION['site_lang_short'] == "ru"){ $data['title'] = "Работа в лучших эскорт агентствах Киева"; $data['SEOh1'] = "Работа в лучших эскорт агентствах Киева"; $data['meta_description'] = "Высокооплачиваемая работа для девушек эскорт ✅ Трудоустройство в элитные эскорт агентства Киева ⭐ Гарантированные выплаты ⭐ Новые вакансии"; }else{ $data['title'] = "Робота в кращих ескорт агентствах Києва"; $data['SEOh1'] = "Робота в кращих ескорт агентствах Києва"; $data['meta_description'] = "Високооплачувана робота для дівчат ескорт ✅ працевлаштування в елітне ескорт агентство Києва ⭐ гарантовані виплати ⭐ нові вакансії"; } $data['ads'] = $this->model->getAds(); $data['pages'] = $this->model->getPagesAds(); $data['filter_page_type'] = 'work'; $this->current_page('work', ''); $this->view->render('front/work', $data, false); } public function tag() { $this->loadModel('front'); extract($this->model->getTagFromSlug($this->slug)); // Если тег не найден в БД — 404 if(isset($data['pages']) && $data['pages'] === false){ $this->view->errorCode(404); die; } // Если структура данных некорректна — инициализируем пустые значения // Пустой список анкет для корректного тега показывается как "нет анкет" if(!isset($data['tags']) || !is_array($data['tags'])){ $this->view->errorCode(404); die; } if(!isset($data['girls']) || !is_array($data['girls'])){ $data['girls'] = []; } if(!isset($data['pages'])){ $data['pages'] = 0; } $temp = get_tag_meta_data($data['tags']); $data['title'] = $temp['title']; $data['SEOh1'] = $temp['SEOh1']; $data['SEOtext'] = $temp['SEOtext']; $data['meta_description'] = $temp['meta_description']; $data['breadcrumb'] = $temp['breadcrumb']; $data['category_link'] = get_category_link(); $data['filter_cat_id'] = isset($data['tags']['id']) ? $data['tags']['id'] : null; $data['filter_page_type'] = 'tag'; if(isset($data['tags']['id']) && $data['tags']['id'] == 26){ $data['filter_page_type'] = 'trans'; } $this->current_page('tag', ''); $view_path = (isset($_SESSION['is_amp']) && $_SESSION['is_amp']) ? 'front/amp/category' : 'front/category'; $use_layout = !empty($_SESSION['is_amp']); $this->view->render($view_path, $data, $use_layout); } public function service() { $this->loadModel('front'); extract($this->model->getServiceFromSlug()); // Если услуга не найдена или метаданные отсутствуют — 404 if (!isset($data['services']) || !is_array($data['services'])) { $this->view->errorCode(404); } // Пустой список анкет для корректной услуги обрабатывается во вьюхе как "нет анкет" if (!isset($data['girls']) || $data['girls'] === false || !is_array($data['girls'])) { $data['girls'] = []; } $temp = get_service_meta_data($data['services']); $data['title'] = $temp['title']; $data['SEOh1'] = $temp['SEOh1']; $data['SEOtext'] = $temp['SEOtext']; $data['meta_description'] = $temp['meta_description']; $data['breadcrumb'] = $temp['breadcrumb']; $data['category_link'] = get_category_link(); $data['filter_cat_id'] = $data['services']['id']; $data['filter_page_type'] = 'service'; $this->current_page('service', ''); $view_path = (isset($_SESSION['is_amp']) && $_SESSION['is_amp']) ? 'front/amp/category' : 'front/category'; $use_layout = !empty($_SESSION['is_amp']); $this->view->render($view_path, $data, $use_layout); } public function girl() { $this->loadModel('front'); $data['girl'] = $this->model->getGirlFromSlug(); $data['review_already_submitted'] = review_already_submitted_for_girl((int)($data['girl']['id'] ?? 0)); $this->model->up_views($data['girl']['id'], $data['girl']['today_views']+1, $data['girl']['all_views']+1); // Метка "мошенник" владельца анкеты $data['alert_user'] = !empty($data['girl']['alert_user']) ? (int)$data['girl']['alert_user'] : 0; // Рандомные анкеты для блока "Другие девушки", исключая текущую $data['girls'] = $this->model->getAnketsForGirl($data['girl']['id'] ?? null); $data['services'] = $this->model->getServicesForGirl(); $data['tags'] = $this->model->getTagsForGirl(); extract(get_girl_meta($data)); $this->current_page('girl', $data['girl']['id']); $view_path = (isset($_SESSION['is_amp']) && $_SESSION['is_amp']) ? 'front/amp/girl' : 'front/girl'; $this->view->render($view_path, $data, false); } public function blog() { $this->loadModel('front'); extract($this->model->getBlogPosts()); $data['title'] = get_trans('blog'); $data['meta_description'] = get_trans('blog_description'); if(isset($_GET['page'])){ $data['title'] = get_trans('blog').'. '.get_trans('page').' '.$_GET['page']; $data['meta_description'] = get_trans('blog_description').' - '.get_trans('page').' '.$_GET['page']; } $this->current_page('rost', ''); $is_amp = isset($_SESSION['is_amp']) && $_SESSION['is_amp']; $view_path = $is_amp ? 'front/amp/blog' : 'front/blog'; // AMP-версия содержит полный документ сама, лейаут не используем $use_layout = false; $this->view->render($view_path, $data, $use_layout); } public function post() { $this->loadModel('front'); $temp = $this->model->getPostSlug($this->slug); if(!in_array($_SESSION['site_lang_short'], $temp['langs'])){ $this->view->errorCode(404); } extract(get_page_meta_data($temp['post'])); $data['post'] = $temp['post']; $data['page_langs'] = $temp['langs']; $data['girls'] = $this->model->getAnketsForGirl(); $this->current_page('post', $data['post']['id']); // Определяем путь для AMP или обычной версии $is_amp = isset($_SESSION['is_amp']) && $_SESSION['is_amp']; $view_path = $is_amp ? 'front/amp/post' : 'front/post'; // AMP-версия содержит полный документ сама, лейаут не используем $use_layout = false; $this->view->render($view_path, $data, $use_layout); } public function get_anket_contact() { try { // Валидация входных данных if (!isset($_POST['id'])) { $this->logContactError('Missing required POST parameters', $_POST); echo ''; die; } if(!isset($_POST['type'])){ $type = 'girl'; }else{ $type = $_POST['type']; } $this->loadModel('front'); $anket = $this->model->getOnlyContactByID($type); if (!$anket) { $this->logContactError('Anket not found', ['type' => $type, 'id' => $_POST['id']]); echo ''; die; } // Увеличиваем счетчик просмотров контактов $this->model->up_contact_views($_POST['id'], $type); $message = urlencode("Здравствуйте, я нашел вас на сайте Kiev-Girls.Info!"); $phone = $anket['phone']; $contacts = []; // Телефон if ($anket['calling']) { $contacts[] = $this->buildPhoneLink($phone); } // Мессенджеры $messengers = [ 'viber' => ['url' => "viber://chat?number=+{$phone}&text={$message}", 'img' => 'viber.png', 'text' => 'Viber'], 'whatsapp' => ['url' => "whatsapp://send?phone=+{$phone}&text={$message}", 'img' => 'whatsapp.png', 'text' => 'WhatsApp'], 'telegram' => ['url' => "tg://resolve?domain={$anket['telegram_nick']}&start={$message}", 'img' => 'telegram.png', 'text' => 'Telegram'] ]; foreach ($messengers as $key => $data) { if ($anket[$key]) { $contacts[] = $this->buildMessengerLink($data); } } echo implode('', $contacts); } catch (Exception $e) { $this->logContactError('Exception in get_anket_contact: ' . $e->getMessage(), [ 'file' => $e->getFile(), 'line' => $e->getLine(), 'post_data' => $_POST ]); echo ''; } die; } private function logContactError($message, $context = []) { $logFile = 'logs/contact_error.log'; $timestamp = date('Y-m-d H:i:s'); $contextStr = !empty($context) ? ' | Context: ' . json_encode($context, JSON_UNESCAPED_UNICODE) : ''; $logEntry = "[{$timestamp}] {$message}{$contextStr}" . PHP_EOL; file_put_contents($logFile, $logEntry, FILE_APPEND | LOCK_EX); } private function buildPhoneLink($phone) { $svg = ''; return '' . $svg . '+' . $phone . ''; } private function buildMessengerLink($data) { $lazy = ($data['img'] !== 'whatsapp.png') ? ' loading="lazy"' : ''; return '' . $data['text'] . ''; } public function salons() { $this->loadModel('front'); if($_SESSION['site_lang_short'] == "ru"){ $content = '

Эротический массаж - отличный способ расслабиться

Эротический массаж - это искусство, которое сочетает в себе умение расслаблять тело и дарить удовольствие. В нашем интимном массажном салоне гости и жители города Киев получают уникальный опыт, который невозможно сравнить с обычным расслабляющим массажем. Эротический массаж в Киеве предлагает разнообразные программы, включающие как классические техники массажа, так и элементы интимного контакта, способные раскрыть эротическую энергию и подарить незабываемые ощущения.

Наши мастера обеспечивают высокий уровень сервиса и индивидуальный подход к каждому гостю. В нашем салоне вы найдете профессиональный эротический массаж для мужчин и женщин, программы для релаксации и снятия стресса, а также возможность выбора сексуальных поз и эротической программы.

Виды эротического массажа

Эротический массаж в Киеве представлен в различных направлениях. Среди основных видов стоит выделить:

Каждая программа нашего интимного салона продумана таким образом, чтобы каждый гость мог выбрать подходящий вид массажа, ориентируясь на личные желания и предпочтения.

Особенности эро массажа

Профессиональный эротический массаж в нашем салоне предполагает особое внимание к каждой детали. Наши мастера обеспечивают комфорт и безопасность, позволяя гостям полностью расслабиться и наслаждаться процессом. Среди преимуществ стоит отметить:

Наш интимный массажный салон - это место, где каждый гость может насладиться качественным эро массажем и получить удовольствие от процесса.

Виды эротического массажа в Киеве

Эротический массаж в Киеве - это уникальная возможность окунуться в мир наслаждений и расслабления. Наш интим салон предлагает широкий выбор программ и услуг, среди которых:

Наши девушки салона эротического массажа в городе Киев профессионально выполняют все программы и создают атмосферу, где гости могут полностью расслабиться и насладиться процессом.

Преимущества эротического массажа в нашем салоне 

Эро массаж в нашем салоне - это уникальная возможность испытать новые ощущения и получить удовольствие на высшем уровне. Каждая процедура создается с учетом индивидуальных предпочтений гостя, благодаря чему каждый сеанс становится полностью персонализированным.

Профессиональные мастера уделяют внимание не только телу, но и эмоциональному состоянию, что позволяет достигнуть максимального эффекта расслабления и наслаждения. В процессе сеанса гости могут выбрать готовую программу или составить индивидуальную с учетом своих желаний, что делает каждую процедуру уникальной и неповторимой.

Особое внимание в нашем салоне уделяется эротической части массажа, которая усиливает чувственные ощущения и дарит чувство гармонии между телом и эмоциями. Благодаря профессионализму мастеров, каждый сеанс проходит в атмосфере доверия и комфорта, где гости могут полностью расслабиться и насладиться процессом без стеснения. Эротическая энергия, передаваемая во время массажа, способствует глубокому расслаблению, снятию стресса и восстановлению эмоционального баланса.

Эро массаж от наших массажисток - это идеальное сочетание профессионализма, интимной атмосферы и максимального комфорта, которое позволяет каждому гостю полностью погрузиться в мир наслаждений и удовольствий. Заказывая сеанс в нашем салоне, вы получаете возможность испытать качественный эротический массаж, насладиться вниманием опытных мастеров и открыть для себя новые ощущения, которые оставят приятные воспоминания на долгое время.

'; }elseif($_SESSION['site_lang_short'] == "uk"){ $content = "

Еротичний масаж - чудовий спосіб розслабитися

Еротичний масаж - це мистецтво, яке поєднує в собі вміння розслабляти тіло та дарувати задоволення. У нашому інтимному масажному салоні гості та жителі міста Київ отримують унікальний досвід, який неможливо порівняти зі звичайним масажем. Еротичний масаж пропонує різноманітні програми, що включають як класичні техніки масажу, так і елементи інтимного контакту, здатні розкрити еротичну енергію і подарувати незабутні відчуття.

Наші майстри забезпечують високий рівень сервісу та індивідуальний підхід до кожного гостя. У нашому салоні ви знайдете професійний еротичний масаж для чоловіків та жінок, програми для релаксації та зняття стресу, а також можливість вибору сексуальних поз та еротичної програми.

Види еротичного масажу

Еротичний масаж у Києві представлений у різних напрямках. Серед основних видів варто виділити:

Кожна програма нашого інтимного салону продумана таким чином, щоб кожен гість міг вибрати відповідний вид масажу, орієнтуючись на особисті бажання та уподобання.

Особливості еро масажу

Професійний еротичний масаж у нашому салоні передбачає особливу увагу до кожної деталі. Наші майстри забезпечують комфорт та безпеку, дозволяючи гостям повністю розслабитися та насолоджуватися процесом. Серед переваг варто відзначити:

Наш інтимний масажний салон - це місце, де кожен гість може насолодитися якісним еро масажем та отримати задоволення від процесу.

Види еротичного масажу в Києві

Еротичний масаж у Києві - це унікальна можливість поринути у світ насолод та розслаблення. Наш інтим салон пропонує широкий вибір програм та послуг, серед яких:

Наші дівчата салону еротичного масажу у місті Київ професійно виконують усі програми та створюють атмосферу, де гості можуть повністю розслабитися та насолодитися процесом.

Переваги еротичного масажу в нашому салоні

Еро масаж у нашому салоні - це унікальна можливість випробувати нові відчуття та отримати задоволення на найвищому рівні. Кожна процедура створюється з урахуванням індивідуальних уподобань гостя, завдяки чому кожен сеанс стає повністю персоналізованим.

Професійні майстри приділяють увагу не тільки тілу, а й емоційному стану, що дозволяє досягти максимального ефекту розслаблення та насолоди. У процесі сеансу гості можуть вибрати готову програму або скласти індивідуальну з урахуванням своїх бажань, що робить кожну процедуру унікальною та неповторною.

Особлива увага в нашому салоні приділяється еротичній частині масажу, яка посилює чуттєві відчуття та дарує почуття гармонії між тілом та емоціями. Завдяки професіоналізму майстрів кожен сеанс проходить в атмосфері довіри та комфорту, де гості можуть повністю розслабитися і насолодитися процесом без сорому. Еротична енергія, що передається під час масажу, сприяє глибокому розслабленню, зняттю стресу та відновленню емоційного балансу.

Еро масаж від наших масажисток - це ідеальне поєднання професіоналізму, інтимної атмосфери та максимального комфорту, яке дозволяє кожному гостю повністю поринути у світ насолод та задоволень. Замовляючи сеанс у нашому салоні, ви отримуєте можливість випробувати якісний еротичний масаж, насолодитися увагою досвідчених майстрів та відкрити для себе нові відчуття.

"; }else{ $content = ''; } $data['page'] = array( 'title' => get_trans('salon_h1'), 'meta_title' => get_trans('salon_meta_title'), 'h1' => get_trans('salon_h1'), 'meta_description' => get_trans('salon_meta_description'), 'content' => $content ); extract(get_page_meta_data($data['page'])); $temp = $this->model->getHomeSalons(); $data['salons'] = $temp['salons']; $data['count_girls'] = $temp['count_girls']; $data['pages'] = $temp['pages']; $tmp = $this->model->getLocationAttrSalons(); $data['metro'] = $tmp['metro']; $data['rajon'] = $tmp['rajon']; $data['filter_page_type'] = 'salons'; $this->current_page('salons', ''); $view_path = (isset($_SESSION['is_amp']) && $_SESSION['is_amp']) ? 'front/amp/salons' : 'front/salons'; $use_layout = !empty($_SESSION['is_amp']); $this->view->render($view_path, $data, $use_layout); } public function salon() { $this->loadModel('front'); if(issetPost()){ switch($_POST['action']){ case 'add_complain': $captcha=$_POST['g-recaptcha-response']; $response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=6Lerh-EpAAAAAL3Kwf0ss5YsRgjPZt2oUD3HTNwa&response=".$captcha."&remoteip=".$_SERVER['REMOTE_ADDR']); $g_response = json_decode($response, true); if($g_response['success']){ $this->model->addComplain('salon'); }else{ echo get_trans('error_recaptcha'); } die; case 'load_more_girl': $this->model->loadMoreGirlForSalon(); } } $data['salon'] = $this->model->getSalonFromSlug(); $data['review_already_submitted'] = review_already_submitted_for_salon((int)($data['salon']['id'] ?? 0)); if($data['salon']['in_catalog'] == 0){ if(!isset($_SESSION['is_auth'])){ $this->view->errorCode(404); }elseif(isset($_SESSION['is_auth']) && $_SESSION['is_auth'] == true && !in_array($data['salon']['id'], $_SESSION['salons_ids']) && $_SESSION['access_level'] == 0){ $this->view->errorCode(404); } } $this->model->up_views_salon($data['salon']['id'], $data['salon']['today_views']+1, $data['salon']['all_views']+1); $data['SEOh1'] = $data['salon'][$_SESSION['site_lang_short'].'_title']; $data['title'] = $data['salon'][$_SESSION['site_lang_short'].'_title']; $data['breadcrumb'] = $data['salon'][$_SESSION['site_lang_short'].'_title']; $this->current_page('salon', $data['salon']['id']); $view_path = (isset($_SESSION['is_amp']) && $_SESSION['is_amp']) ? 'front/amp/salon' : 'front/salon'; // AMP-шаблон салона — полный HTML-документ (header_amp + main + footer), как front/amp/girl.php. // layout/amp.php нельзя подключать: иначе дублируются хедер и футер. $use_layout = false; $this->view->render($view_path, $data, $use_layout); } public function age() { if($_SESSION['site_lang_id'] == 1){ $data['cat_slug'] = 'vozrast'; if(strpos(get_uri_segment(1), '+') === false){ $post_slug = explode('-',substr(get_uri_segment(1),4, 10)); $cat_link = 'age-'.substr(get_uri_segment(1),4, 10).'/'; }else{ $cat_link = 'age-'.intval(substr(get_uri_segment(1), 4, 10)).'+/'; $post_slug[0] = intval(substr(get_uri_segment(1), 4, 10)); $post_slug[1] = 999; } $title = substr(get_uri_segment(1),4,10); }else{ $data['cat_slug'] = 'vozrast'; if(strpos(get_uri_segment(2), '+') === false){ $post_slug = explode('-',substr(get_uri_segment(2),4, 10)); $cat_link = 'age-'.substr(get_uri_segment(2),4, 10).'/'; }else{ $cat_link = 'age-'.intval(substr(get_uri_segment(2), 4, 10)).'+/'; $post_slug[0] = intval(substr(get_uri_segment(2), 4, 10)); $post_slug[1] = 999; } $title = substr(get_uri_segment(2),4,10); } if(isset($_GET['page'])){ $page_num = $_GET['page']; }else{ $page_num = 1; } if($page_num > 1){ $add_str = '. '.get_trans('page').' '.$page_num; }else{ $add_str = ''; } $this->loadModel('front'); extract($this->model->getGirlFromVozrast($post_slug)); // Если фильтр возраста не найден или структура данных некорректна — 404 // Пустой список анкет для корректного фильтра показывается как "нет анкет" if(!array_key_exists('girls', $data) || !is_array($data['girls'])){ $this->view->errorCode(404); } $data['title'] = str_replace('$$', $title, get_trans('vozrast_tit')).$add_str; $data['meta_description'] = str_replace('$$', $title, get_trans('vozrast_desc')); $data['SEOh1'] = str_replace('$$', $title, get_trans('vozrast_h1')).$add_str; $data['SEOtext'] = ''; /* dd($data); if($data['page']['meta_title'] != "" && !is_null($data['page']['meta_title'])){ $data['title'] = $data['page']['meta_title']; } if($data['page']['meta_description'] != "" && !is_null($data['page']['meta_description'])){ $data['meta_description'] = $data['page']['meta_description']; } if($data['page']['SEOh1'] != "" && !is_null($data['page']['SEOh1'])){ $data['SEOh1'] = $data['page']['SEOh1']; } if($data['page']['SEOtext'] != "" && !is_null($data['page']['SEOtext'])){ $data['SEOtext'] = $data['page']['SEOtext']; } */ if(isset($_GET['page'])){ $data['meta_description'] .= ' - '.get_trans('page').' '.$_GET['page']; } $data['breadcrumb'] = get_trans('vozrast').' '.$title.' '.get_trans('vozrast_val'); $data['category_link'] = $cat_link; $data['filter_page_type'] = 'home'; $this->current_page('age', ''); $this->view->render('front/category', $data, false); } public function rost() { if($_SESSION['site_lang_id'] == 1){ if(strpos(get_uri_segment(1), '+') === false){ $cat_link = 'rost-'.substr(get_uri_segment(1),5, 10).'/'; $post_slug = explode('-',substr(get_uri_segment(1),5, 10)); }else{ $cat_link = 'rost-'.intval(substr(get_uri_segment(1), 5, 10)).'+/'; $post_slug[0] = intval(substr(get_uri_segment(1), 5, 10)); $post_slug[1] = 999; } $title = substr(get_uri_segment(1),5,10); }else{ $data['cat_slug'] = 'rost'; if(strpos(get_uri_segment(2), '+') === false){ $cat_link = 'rost-'.substr(get_uri_segment(2),5, 10).'/'; $post_slug = explode('-',substr(get_uri_segment(2),5, 10)); }else{ $cat_link = 'rost-'.intval(substr(get_uri_segment(2), 5, 10)).'+/'; $post_slug[0] = intval(substr(get_uri_segment(2), 5, 10)); $post_slug[1] = 999; } $title = substr(get_uri_segment(2),5,10); } if($post_slug[0] == 160){ $post_slug[0] = 0; $post_slug[1] = 160; $title = 'до 160'; } if(isset($_GET['page'])){ $page_num = $_GET['page']; }else{ $page_num = 1; } if($page_num > 1){ $add_str = '. '.get_trans('page').' '.$page_num; }else{ $add_str = ''; } $data['filter_page_type'] = 'home'; $this->loadModel('front'); extract($this->model->getGirlFromRost($post_slug)); // Если фильтр роста не найден или структура данных некорректна — 404 // Пустой список анкет для корректного фильтра показывается как "нет анкет" if(!array_key_exists('girls', $data) || !is_array($data['girls'])){ $this->view->errorCode(404); } $data['title'] = str_replace('$$', $title, get_trans('rost_tit')).$add_str; $data['meta_description'] = str_replace('$$', $title, get_trans('rost_desc')); $data['SEOh1'] = str_replace('$$', $title, get_trans('rost_h1')).$add_str; $data['SEOtext'] = ''; /* if($data['page']['meta_title'] != "" && !is_null($data['page']['meta_title'])){ $data['title'] = $data['page']['meta_title']; } if($data['page']['meta_description'] != "" && !is_null($data['page']['meta_description'])){ $data['meta_description'] = $data['page']['meta_description']; } if($data['page']['SEOh1'] != "" && !is_null($data['page']['SEOh1'])){ $data['SEOh1'] = $data['page']['SEOh1']; } if($data['page']['SEOtext'] != "" && !is_null($data['page']['SEOtext'])){ $data['SEOtext'] = $data['page']['SEOtext']; } */ if(isset($_GET['page'])){ $data['meta_description'] .= ' - '.get_trans('page').' '.$_GET['page']; } $data['category_link'] = $cat_link; $data['breadcrumb'] = get_trans('rost').' '.$title.' '.get_trans('rost_val'); $data['filter_page_type'] = 'home'; $this->current_page('rost', ''); $this->view->render('front/category', $data, false); } public function weight() { if($_SESSION['site_lang_id'] == 1){ $data['cat_slug'] = 'ves'; if(strpos(get_uri_segment(1), '+') === false){ $post_slug = explode('-',substr(get_uri_segment(1),7, 10)); $cat_link = 'weight-'.substr(get_uri_segment(1),7, 10).'/'; }else{ $cat_link = 'weight-'.intval(substr(get_uri_segment(1), 7, 10)).'+/'; $post_slug[0] = intval(substr(get_uri_segment(1), 7, 10)); $post_slug[1] = 999; } $title = substr(get_uri_segment(1),7,10); }else{ $data['cat_slug'] = 'ves'; if(strpos(get_uri_segment(2), '+') === false){ $cat_link = 'weight-'.substr(get_uri_segment(2),7, 10).'/'; $post_slug = explode('-',substr(get_uri_segment(2),7, 10)); }else{ $cat_link = 'weight-'.intval(substr(get_uri_segment(2), 7, 10)).'+/'; $post_slug[0] = intval(substr(get_uri_segment(2), 7, 10)); $post_slug[1] = 999; } $title = substr(get_uri_segment(2),7,10); } if(isset($_GET['page'])){ $page_num = $_GET['page']; }else{ $page_num = 1; } if($page_num > 1){ $add_str = '. '.get_trans('page').' '.$page_num; }else{ $add_str = ''; } $this->loadModel('front'); extract($this->model->getGirlFromWeight($post_slug)); // Если фильтр веса не найден или структура данных некорректна — 404 // Пустой список анкет для корректного фильтра показывается как "нет анкет" if(!array_key_exists('girls', $data) || !is_array($data['girls'])){ $this->view->errorCode(404); } $data['title'] = str_replace('$$', $title, get_trans('ves_tit')).$add_str; $data['meta_description'] = str_replace('$$', $title, get_trans('ves_desc')); $data['SEOh1'] = str_replace('$$', $title, get_trans('ves_h1')).$add_str; $data['SEOtext'] = ''; /* if($data['page']['meta_title'] != "" && !is_null($data['page']['meta_title'])){ $data['title'] = $data['page']['meta_title']; } if($data['page']['meta_description'] != "" && !is_null($data['page']['meta_description'])){ $data['meta_description'] = $data['page']['meta_description']; } if($data['page']['SEOh1'] != "" && !is_null($data['page']['SEOh1'])){ $data['SEOh1'] = $data['page']['SEOh1']; } if($data['page']['SEOtext'] != "" && !is_null($data['page']['SEOtext'])){ $data['SEOtext'] = $data['page']['SEOtext']; } */ if(isset($_GET['page'])){ $data['meta_description'] .= ' - '.get_trans('page').' '.$_GET['page']; } $data['category_link'] = $cat_link; $data['breadcrumb'] = get_trans('ves').' '.$title.' '.get_trans('ves_val'); $data['filter_page_type'] = 'home'; $this->current_page('rost', ''); $this->view->render('front/category', $data, false); } public function razmer() { $this->loadModel('front'); // Получаем последний сегмент URL $uri_segment = $this->model->getUrlLastSlug(); // Извлекаем размер из URL (формат: breast-size-1, breast-size-1.5 и т.д.) if(strpos($uri_segment, 'breast-size-') !== false){ $post_slug = str_replace('breast-size-', '', $uri_segment); }else{ // Fallback на старый способ для совместимости if($_SESSION['site_lang_id'] == 1){ $post_slug = substr(get_uri_segment(1),12); }else{ $post_slug = substr(get_uri_segment(2),12); } // Убираем возможные лишние символы $post_slug = rtrim($post_slug, '/'); } if(isset($_GET['page'])){ $page_num = $_GET['page']; }else{ $page_num = 1; } if($page_num > 1){ $add_str = '. '.get_trans('page').' '.$page_num; }else{ $add_str = ''; } // Для английской версии преобразуем размер в букву if($_SESSION['site_lang_short'] == "en"){ // Маппинг размеров на буквы: 1->A, 2->B, 3->C, 4->D, 5->DD, 6->E, 7->F $size_map = [ '1' => 'A', '1.5' => 'A', '2' => 'B', '2.5' => 'B', '3' => 'C', '3.5' => 'C', '4' => 'D', '4.5' => 'D', '5' => 'DD', '5.5' => 'DD', '6' => 'E', '7' => 'F' ]; $title = isset($size_map[$post_slug]) ? $size_map[$post_slug] : $post_slug; }else{ $title = $post_slug; } $this->loadModel('front'); extract($this->model->getGirlFromRazmer($post_slug)); // Если фильтр размера не найден или структура данных некорректна — 404 // Пустой список анкет для корректного фильтра показывается как "нет анкет" if(!array_key_exists('girls', $data) || !is_array($data['girls'])){ $this->view->errorCode(404); } $data['title'] = str_replace('$$', $title, get_trans('razmer_tit')).$add_str; $data['meta_description'] = str_replace('$$', $title, get_trans('razmer_desc')); $data['SEOh1'] = str_replace('$$', $title, get_trans('razmer_h1')).$add_str; $data['SEOtext'] = ''; /* if($data['page']['meta_title'] != "" && !is_null($data['page']['meta_title'])){ $data['title'] = $data['page']['meta_title']; } if($data['page']['meta_description'] != "" && !is_null($data['page']['meta_description'])){ $data['meta_description'] = $data['page']['meta_description']; } if($data['page']['SEOh1'] != "" && !is_null($data['page']['SEOh1'])){ $data['SEOh1'] = $data['page']['SEOh1']; } */ if($data['page']['SEOtext'] != "" && !is_null($data['page']['SEOtext'])){ $data['SEOtext'] = $data['page']['SEOtext']; }else{ $data['SEOtest'] = ""; } if(isset($_GET['page'])){ $data['meta_description'] .= ' - '.get_trans('page').' '.$_GET['page']; } $data['category_link'] = 'breast-size-'.$post_slug.'/'; $data['breadcrumb'] = get_trans('grudi').' '.$title; $data['filter_page_type'] = 'home'; $this->current_page('rost', ''); $this->view->render('front/category', $data, false); } public function page_prices() { $this->loadModel('front'); // Получаем URI сегмент - используем метод модели для получения последнего сегмента $uri_segment = $this->model->getUrlLastSlug(); // Определяем переводы для "от" и "до" в зависимости от языка $lang = $_SESSION['site_lang_short']; $price_from = ['ru' => 'от', 'uk' => 'від', 'en' => 'from', 'tr' => 'itibaren']; $price_to = ['ru' => 'до', 'uk' => 'до', 'en' => 'to', 'tr' => 'kadar']; $from = isset($price_from[$lang]) ? $price_from[$lang] : $price_from['ru']; $to = isset($price_to[$lang]) ? $price_to[$lang] : $price_to['ru']; // Обрабатываем разные варианты URL: czena-ot- и czena-do- if(strpos($uri_segment, 'czena-do-') !== false){ $post_slug = str_replace('czena-do-', '', $uri_segment); $prices = [0, intval($post_slug)]; // "до X" означает от 0 до X $title = $to.' '.$prices[1]; $category_link_prefix = 'czena-do-'; }elseif(strpos($uri_segment, 'czena-ot-') !== false){ $post_slug = str_replace('czena-ot-', '', $uri_segment); if(strpos($post_slug, "-do-") !== false){ $prices = explode("-do-", $post_slug); $prices = array_map('intval', $prices); $title = $from.' '.$prices[0].' '.$to.' '.$prices[1]; }else{ $prices = [intval($post_slug)]; $title = $from.' '.$prices[0]; } $category_link_prefix = 'czena-ot-'; }else{ // Если формат не распознан - 404 $this->view->errorCode(404); die; } if(isset($_GET['page'])){ $page_num = $_GET['page']; }else{ $page_num = 1; } if($page_num > 1){ $add_str = '. '.get_trans('page').' '.$page_num; }else{ $add_str = ''; } extract($this->model->getGirlFromPrices($prices)); // Если структура данных некорректна — инициализируем пустые значения // Пустой список анкет для корректного фильтра показывается как "нет анкет" if(!isset($data) || !is_array($data)){ $data = []; } if(!isset($data['girls']) || !is_array($data['girls'])){ $data['girls'] = []; } if(!isset($data['pages'])){ $data['pages'] = 0; } $data['title'] = str_replace('$$', $title, get_trans('page_prices_tit')).$add_str; $data['meta_description'] = str_replace('$$', $title, get_trans('page_prices_desc')); $data['SEOh1'] = str_replace('$$', $title, get_trans('page_prices_h1')).$add_str; $data['SEOtext'] = ''; if(isset($_GET['page'])){ $data['meta_description'] .= ' - '.get_trans('page').' '.$_GET['page']; } $data['category_link'] = $category_link_prefix.$post_slug.'/'; $data['breadcrumb'] = $title; $data['filter_page_type'] = 'home'; $this->current_page('rost', ''); $this->view->render('front/category', $data, false); } public function metro() { $this->loadModel('front'); extract($this->model->getMetro()); // Если метро не найдено — 404 if(!isset($metro) || !is_array($metro)){ $this->view->errorCode(404); die; } // Если структура данных некорректна — инициализируем пустые значения // Пустой список анкет для корректного метро показывается как "нет анкет" if(!isset($data) || !array_key_exists('girls', $data) || !is_array($data['girls'])){ $data['girls'] = []; $data['pages'] = 0; } if(isset($_GET['page'])){ $page_num = $_GET['page']; }else{ $page_num = 1; } if($page_num > 1){ $add_str = '. '.get_trans('page').' '.$page_num; }else{ $add_str = ''; } if(!is_null($metro['meta_title']) && $metro['meta_title'] != ""){ $data['title'] = $metro['meta_title'].$add_str; }else{ $data['title'] = str_replace('$$', $metro['title'], get_trans('metro_tit')).$add_str; } if(!is_null($metro['meta_description']) && $metro['meta_description'] != ""){ $data['meta_description'] = $metro['meta_description'].$add_str; }else{ $data['meta_description'] = str_replace('$$', $metro['title'], get_trans('metro_desc')); } if(isset($_GET['page'])){ $data['meta_description'] .= ' - '.get_trans('page').' '.$_GET['page']; } if(!is_null($metro['SEOh1']) && $metro['SEOh1'] != ""){ $data['SEOh1'] = $metro['SEOh1'].$add_str; }else{ $data['SEOh1'] = str_replace('$$', $metro['title'], get_trans('metro_h1')).$add_str; } if(!is_null($metro['SEOtext']) && $metro['SEOtext'] != ""){ $data['SEOtext'] = $metro['SEOtext']; }else{ $data['SEOtext'] = ''; } $data['breadcrumb'] = get_trans('metro').' "'.$metro['title'].'"'; $data['category_link'] = 'metro/'.$metro['slug'].'/'; $data['filter_cat_id'] = $metro['id']; $data['filter_page_type'] = 'metro'; $this->current_page('rost', ''); // AMP / обычная версия метро-страницы $view_path = (isset($_SESSION['is_amp']) && $_SESSION['is_amp']) ? 'front/amp/category' : 'front/category'; $use_layout = !empty($_SESSION['is_amp']); $this->view->render($view_path, $data, $use_layout); } public function rajon() { $this->loadModel('front'); extract($this->model->getRajon()); // Если район не найден — 404 if(!isset($rajon) || !is_array($rajon)){ $this->view->errorCode(404); die; } // Если структура данных некорректна — 404 // Пустой список анкет для корректного района показывается как "нет анкет" if(!isset($data) || !array_key_exists('girls', $data) || !is_array($data['girls'])){ $data['girls'] = []; $data['pages'] = 0; } if(isset($_GET['page'])){ $page_num = $_GET['page']; }else{ $page_num = 1; } if($page_num > 1){ $add_str = '. '.get_trans('page').' '.$page_num; }else{ $add_str = ''; } if(!is_null($rajon['meta_title']) && $rajon['meta_title'] != ""){ $data['title'] = $rajon['meta_title'].$add_str; }else{ $data['title'] = str_replace('$$', $rajon['title'], get_trans('rajon_tit')).$add_str; } if(!is_null($rajon['meta_description']) && $rajon['meta_description'] != ""){ $data['meta_description'] = $rajon['meta_description'].$add_str; }else{ $data['meta_description'] = str_replace('$$', $rajon['title'], get_trans('rajon_desc')); } if(!is_null($rajon['SEOh1']) && $rajon['SEOh1'] != ""){ $data['SEOh1'] = $rajon['SEOh1'].$add_str; }else{ $data['SEOh1'] = str_replace('$$', $rajon['title'], get_trans('rajon_h1')).$add_str; } if(!is_null($rajon['SEOtext']) && $rajon['SEOtext'] != ""){ $data['SEOtext'] = $rajon['SEOtext']; }else{ $data['SEOtext'] = ''; } if(isset($_GET['page'])){ $data['meta_description'] .= ' - '.get_trans('page').' '.$_GET['page']; } $data['breadcrumb'] = get_trans('rajon').' "'.$rajon['title'].'"'; $data['category_link'] = 'rajon/'.$rajon['slug'].'/'; $data['filter_cat_id'] = $rajon['id']; $data['filter_page_type'] = 'rajon'; $this->current_page('rost', ''); // AMP / обычная версия район-страницы $view_path = (isset($_SESSION['is_amp']) && $_SESSION['is_amp']) ? 'front/amp/category' : 'front/category'; $use_layout = !empty($_SESSION['is_amp']); $this->view->render($view_path, $data, $use_layout); } public function new_girls() { $this->loadModel('front'); $data['page'] = $this->model->getNewPage(); $meta = (!empty($data['page']) && is_array($data['page'])) ? get_page_meta_data($data['page']) : ['data' => ['title' => '', 'meta_description' => '', 'SEOh1' => '', 'SEOtext' => '']]; $data = array_merge($data, $meta['data'] ?? []); $temp = $this->model->getNewGirls(); $data['girls'] = $temp['girls']; $data['pages'] = $temp['pages']; $data['filter_page_type'] = 'home'; $this->current_page('rost', ''); $view_path = (isset($_SESSION['is_amp']) && $_SESSION['is_amp']) ? 'front/amp/home' : 'front/home'; $use_layout = !empty($_SESSION['is_amp']); $this->view->render($view_path, $data, $use_layout); } public function reviews() { $this->loadModel('front'); $data['page'] = $this->model->getReviewPage(); extract(get_page_meta_data($data['page'])); $temp = $this->model->getReviewGirls(); $data['reviews'] = $temp['girls']; $data['pages'] = $temp['pages']; $data['filter_page_type'] = 'home'; $this->current_page('reviews', ''); $this->view->render('front/reviews', $data, false); } public function webmaster() { if(issetPost()){ $msg = "Имя: {$_POST['name']}\nEmail: {$_POST['email']}\nСообщение: {$_POST['message']}"; mail('gilsonsat4@protonmail.com', 'Заявка с формы "Вебмастерам" сайта KievGirls', $msg, 'From: KievGirls '); } $data['title'] = get_trans('webmaster_menu'); $data['SEOh1'] = get_trans('webmaster_h1'); $data['filter_page_type'] = 'home'; $this->current_page('rost', ''); $this->view->render('front/webmaster', $data, false); } public function add_review_girl() { $this->loadModel('front'); $captcha = isset($_POST['g-recaptcha-response']) ? $_POST['g-recaptcha-response'] : ''; $okCaptcha = true; if (kg_is_production()) { $response = @file_get_contents( 'https://www.google.com/recaptcha/api/siteverify?secret=6LcKprYpAAAAADsNs2FfXYNI1VtvNpTox_BH4tvc&response=' . urlencode($captcha) . '&remoteip=' . urlencode($_SERVER['REMOTE_ADDR'] ?? '') ); $g_response = $response ? json_decode($response, true) : null; $okCaptcha = is_array($g_response) && !empty($g_response['success']); } if (!$okCaptcha) { echo json_encode(['status' => 0, 'content' => '

' . get_trans('error_review') . '

']); die; } if (isset($_POST['salon_id'])) { $sid = (int)$_POST['salon_id']; if ($sid <= 0 || review_already_submitted_for_salon($sid)) { echo json_encode(['status' => 0, 'content' => '

' . get_trans('review_already_submitted') . '

']); die; } $this->model->add_review_salon(); } else { $gid = (int)($_POST['girl_id'] ?? 0); if ($gid <= 0 || review_already_submitted_for_girl($gid)) { echo json_encode(['status' => 0, 'content' => '

' . get_trans('review_already_submitted') . '

']); die; } $this->model->add_review_girl(); } die; } public function main_sitemap() { $this->loadModel('front'); extract($this->model->getSitemapDate()); $this->current_page('rost', ''); $this->view->render('front/sitemap', $data, false); } public function post_sitemap() { $this->loadModel('front'); extract($this->model->getPostSitemap()); $data['type'] = 'post'; $this->current_page('rost', ''); $this->view->render('front/type_sitemap', $data, false); } public function page_sitemap() { $this->loadModel('front'); extract($this->model->getPageSitemap()); $data['type'] = 'page'; $this->current_page('rost', ''); $this->view->render('front/type_sitemap', $data, false); } public function service_sitemap() { $this->loadModel('front'); extract($this->model->getServiceSitemap()); $data['type'] = 'service'; $this->current_page('rost', ''); $this->view->render('front/type_sitemap', $data, false); } public function ladies_sitemap() { $this->loadModel('front'); extract($this->model->getTagSitemap()); $data['type'] = 'ladies'; $this->current_page('rost', ''); $this->view->render('front/type_sitemap', $data, false); } public function model_sitemap() { $this->loadModel('front'); extract($this->model->getGirlSitemap()); $data['type'] = 'anket'; $this->current_page('rost', ''); $this->view->render('front/girl_sitemap', $data, false); } public function metro_sitemap() { $this->loadModel('front'); extract($this->model->getMetroSitemap()); $data['type'] = 'metro'; $this->current_page('rost', ''); $this->view->render('front/type_sitemap', $data, false); } public function rajon_sitemap() { $this->loadModel('front'); extract($this->model->getRajonSitemap()); $data['type'] = 'rajon'; $this->current_page('rost', ''); $this->view->render('front/type_sitemap', $data, false); } public function current_page($type, $id) { $_SESSION['page_type'] = $type; $_SESSION['curr_ID'] = $id; } private function getRequestHeaders() { if (function_exists('getallheaders')) { return getallheaders(); } $headers = []; foreach ($_SERVER as $name => $value) { if (strpos($name, 'HTTP_') === 0) { $headerName = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5))))); $headers[$headerName] = $value; } } return $headers; } /** * Получает IP адрес пользователя */ private function getUserIp() { if (!empty($_SERVER['HTTP_CLIENT_IP'])) { $ip = $_SERVER['HTTP_CLIENT_IP']; } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; } else { $ip = $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0'; } // Если в 'HTTP_X_FORWARDED_FOR' несколько IP, взять первый if (strpos($ip, ',') !== false) { $ip = explode(',', $ip)[0]; } return trim($ip); } } view->errorCode($code); } public function errorCore($text) { $this->view->errorCore($text); } } Internal Server Error