diff --git a/wp-content/themes/cosmopet/modules/forms/module-controller.php b/wp-content/themes/cosmopet/modules/forms/module-controller.php index 144ebc3..e97a8fc 100644 --- a/wp-content/themes/cosmopet/modules/forms/module-controller.php +++ b/wp-content/themes/cosmopet/modules/forms/module-controller.php @@ -15,6 +15,9 @@ abstract class FormHandler { } } +define('WEBHOOK_URL', 'https://b24-f0tsii.bitrix24.ru/rest/10/z5k521mjfkmk7pqj/'); +$utm_data = get_utm_data(); + class b24Handler extends FormHandler { public function handle($data) { // Логика отправки в Mailchimp @@ -23,6 +26,365 @@ class b24Handler extends FormHandler { // Вызываем следующий обработчик в цепочке return parent::handle($data); } + + + +function b24_get_or_create_contact($phone, $name, $email, $utm, $userID = null, $isSubscribe) { + $contactId = null; + $error = null; + $foundContacts = []; + + if (empty($email) && empty($phone) && empty($userID)) { + return ['contact_id' => null, 'error' => 'Не указаны контактные данные']; + } + + // Получаем telegram username если указан userID + $tg_username = ''; + if (!empty($userID)) { + $tg_username = get_user_meta($userID, 'tg_username', true); + } + + // 1. Поиск по всем возможным комбинациям (включая userID) + $searchFilters = []; + + if (!empty($userID)) { + $searchFilters[] = ['UF_CRM_1744373080655' => $userID]; + } + + if (!empty($phone)) $searchFilters[] = ['PHONE' => $phone]; + if (!empty($email)) $searchFilters[] = ['EMAIL' => $email]; + + foreach ($searchFilters as $filter) { + $response = b24_request('crm.contact.list', [ + 'filter' => $filter, + 'select' => ['ID', 'NAME', 'PHONE', 'EMAIL', 'UF_CRM_1744373080655', 'IM'] + ]); + + if (!empty($response['result'])) { + $foundContacts = array_merge($foundContacts, $response['result']); + } + } + + // 2. Обработка найденных контактов + if (!empty($foundContacts)) { + $bestMatch = null; + $maxMatches = 0; + + foreach ($foundContacts as $contact) { + $matches = 0; + + if (!empty($userID) && isset($contact['UF_CRM_1744373080655']) && $contact['UF_CRM_1744373080655'] == $userID) { + $matches += 3; + } + + if (!empty($phone) && valueExists($contact['PHONE'] ?? [], $phone)) $matches++; + if (!empty($email) && valueExists($contact['EMAIL'] ?? [], $email)) $matches++; + + if ($matches > $maxMatches) { + $maxMatches = $matches; + $bestMatch = $contact; + } + } + + if ($bestMatch) { + $contactId = $bestMatch['ID']; + $updateFields = []; + + if ($name && (empty($bestMatch['NAME']) || $bestMatch['NAME'] != $name)) { + $updateFields['NAME'] = $name; + } + + if (!empty($phone) && !valueExists($bestMatch['PHONE'] ?? [], $phone)) { + $updateFields['PHONE'][] = ['VALUE' => $phone, 'VALUE_TYPE' => 'MOBILE']; + } + + if (!empty($email) && !valueExists($bestMatch['EMAIL'] ?? [], $email)) { + $updateFields['EMAIL'][] = ['VALUE' => $email, 'VALUE_TYPE' => 'WORK']; + } + + // Добавляем Telegram если есть username и его еще нет в контакте + if (!empty($tg_username) && !imExists($bestMatch['IM'] ?? [], $tg_username)) { + $updateFields['IM'][] = [ + 'VALUE' => $tg_username, + 'VALUE_TYPE' => 'TELEGRAM', + 'TYPE_ID' => 'TELEGRAM' + ]; + } + + if (!empty($utm)) { + $updateFields['UTM_SOURCE'] = $utm; + } + + if (!empty($userID) && (!isset($bestMatch['UF_CRM_1744373080655']) || $bestMatch['UF_CRM_1744373080655'] != $userID)) { + $updateFields['UF_CRM_1744373080655'] = $userID; + } + + if ($isSubscribe) { + $updateFields['UF_CRM_1744562461053'] = true; + } + + if (!empty($updateFields)) { + $updateResponse = b24_request('crm.contact.update', [ + 'id' => $contactId, + 'fields' => $updateFields + ]); + + if (!empty($updateResponse['error'])) { + $error = 'Ошибка обновления: '.$updateResponse['error']; + } + } + } + } + // 3. Создание нового контакта если не найдено совпадений + else { + $utm_source = get_utm_data()['utm_source'] ?? ''; + $utm_medium = get_utm_data()['utm_medium'] ?? ''; + $utm_campaign = get_utm_data()['utm_campaign'] ?? ''; + $utm_content = get_utm_data()['utm_content'] ?? ''; + $utm_term = get_utm_data()['utm_term'] ?? ''; + + $newContact = [ + 'fields' => [ + 'NAME' => $name, + 'SOURCE_ID' => "WEB", + 'TYPE_ID' => "CLIENT", + 'OPENED' => "Y", + 'UTM_SOURCE' => $utm_source, + 'UTM_MEDIUM' => $utm_medium, + 'UTM_CAMPAIGN' => $utm_campaign, + 'UTM_CONTENT' => $utm_content, + 'UTM_TERM' => $utm_term, + ] + ]; + + if (!empty($phone)) { + $newContact['fields']['PHONE'][] = ['VALUE' => $phone, 'VALUE_TYPE' => 'MOBILE']; + } + if (!empty($email)) { + $newContact['fields']['EMAIL'][] = ['VALUE' => $email, 'VALUE_TYPE' => 'WORK']; + } + if (!empty($utm)) { + $newContact['fields']['UTM_SOURCE'] = $utm; + } + if (!empty($userID)) { + $newContact['fields']['UF_CRM_1744373080655'] = $userID; + } + if ($isSubscribe) { + $newContact['fields']['UF_CRM_1744562461053'] = true; + } + // Добавляем Telegram при создании нового контакта + if (!empty($tg_username)) { + $newContact['fields']['IM'][] = [ + 'VALUE' => $tg_username, + 'VALUE_TYPE' => 'TELEGRAM', + 'TYPE_ID' => 'TELEGRAM' + ]; + } + + $response = b24_request('crm.contact.add', $newContact); + $contactId = $response['result'] ?? null; + $error = $response['error'] ?? null; + } + + return ['contact_id' => $contactId, 'error' => $error]; +} + +// Вспомогательная функция для проверки значений +function valueExists($items, $value) { + foreach ($items as $item) { + if ($item['VALUE'] == $value) return true; + } + return false; +} + +/* Функция POST-запроса к API Bitrix24 по адреcу Веб-хука */ +function b24_request($method, $params = []) { + $url = WEBHOOK_URL . $method; // ТУТ ВСТАВЛЯЕМ ХУК ОТ ИНТЕГРАТОРА + $curl = curl_init(); + curl_setopt_array($curl, [ + CURLOPT_URL => $url, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_POST => true, + CURLOPT_POSTFIELDS => http_build_query($params), + CURLOPT_TIMEOUT => 3, // Максимальное время выполнения запроса (в секундах) + CURLOPT_CONNECTTIMEOUT => 2, // Максимальное время ожидания соединения (в секундах) + ]); + $response = curl_exec($curl); + if ($response === false) { + // Обработка ошибок + return ['error' => curl_error($curl)]; + } + error_log('CURL URL: ' . $url); + error_log('CURL RESP: ' . $response); + + curl_close($curl); + return json_decode($response, true); +} + +function b24_send_lead($contactId, $msg, $stage, $fName, $order_total, $method, $form_title, $order_id) { + // Собираем UTM-метки из URL или POST данных + $utm_data = get_utm_data(); + $utm_source = $utm_data['utm_source'] ?? ''; + $utm_medium = $utm_data['utm_medium'] ?? ''; + $utm_campaign = $utm_data['utm_campaign'] ?? ''; + $utm_content = $utm_data['utm_content'] ?? ''; + $utm_term = $utm_data['utm_term'] ?? ''; + + // Подготавливаем данные для сделки + $dealData = [ + 'fields' => [ + 'TITLE' => $form_title . ' - ' . $_SERVER['HTTP_HOST'], + "STAGE_ID"=> $stage, + 'CONTACT_ID' => $contactId, + 'CATEGORY_ID' => $fName, + 'SOURCE_ID' => "WEB", + // 'ASSIGNED_BY_ID' => "000", + 'SOURCE_DESCRIPTION' => '', + // Добавляем UTM-метки + 'UTM_SOURCE' => $utm_source, + 'UTM_MEDIUM' => $utm_medium, + 'UTM_CAMPAIGN' => $utm_campaign, + 'UTM_CONTENT' => $utm_content, + 'UTM_TERM' => $utm_term, + // Можно добавить дополнительные поля + 'COMMENTS' => $msg, + 'OPPORTUNITY' => $order_total, + ] + ]; + + if ($order_id){ + $dealData['fields']['UF_CRM_1745741833259'] = $order_id; + } + error_log('DEAL DATA: ' . json_encode($dealData)); + // Отправляем данные в Bitrix24 + $newDealResponse = b24_request($method, $dealData); + error_log('DEAL RESP: ' . json_encode($newDealResponse)); + // Обработка ответа + $error = null; + if (!empty($newDealResponse['error'])) { + $error = $newDealResponse['error']; + } elseif (empty($newDealResponse['result'])) { + $error = 'Ошибка создания сделки'; + } + + // Возвращаем результат + return [ + 'success' => empty($error), + 'contact_id' => $contactId, + 'error' => $error, + 'utm' => [ + 'source' => $utm_source, + 'medium' => $utm_medium, + 'campaign' => $utm_campaign, + 'content' => $utm_content, + 'term' => $utm_term + ] + ]; +} + + + + function b24_add_lead($phone, $name, $email, $msg, $utm, $url, $stage, $fName, $order_total=0, $userID=null, $method = 'crm.deal.add', $form_title, $isSubscribe=false, $order_id=''){ + $contact = b24_get_or_create_contact($phone, $name, $email, $utm, $userID, $isSubscribe); + if (!empty($contact['contact_id'])){ + $contactId = $contact['contact_id']; + } + else{ + return ['error' => $contact['error']]; + } + + $msg = $msg . ' + Отправлено со страницы: ' . $url; + b24_send_lead($contactId, $msg, $stage, $fName, $order_total, $method, $form_title, $order_id); + } + + function b24_update_contact_by_user_id($userID, $newData) { + if (empty($userID)) { + return ['success' => false, 'error' => 'Не указан ID пользователя']; + } + + // Получаем текущие данные пользователя + $user = get_user_by('ID', $userID); + if (!$user) { + return ['success' => false, 'error' => 'Пользователь не найден']; + } + + // Получаем telegram username + $tg_username = get_user_meta($userID, 'tg_username', true); + + // Ищем контакт по ID пользователя + $response = b24_request('crm.contact.list', [ + 'filter' => ['UF_CRM_1744373080655' => $userID], + 'select' => ['ID', 'NAME', 'PHONE', 'EMAIL', 'UF_CRM_1744373080655', 'IM', 'UF_CRM_1744562461053'] + ]); + + if (empty($response['result'])) { + return ['success' => false, 'error' => 'Контакт не найден в Bitrix24']; + } + + $contact = $response['result'][0]; + $contactId = $contact['ID']; + $updateFields = []; + + // Обновляем имя, если оно изменилось + if (isset($newData['name']) && $newData['name'] !== $contact['NAME']) { + $updateFields['NAME'] = $newData['name']; + } + + // Обновляем телефон, если он изменился + if (isset($newData['phone'])) { + $phoneExists = false; + foreach ($contact['PHONE'] ?? [] as $phoneItem) { + if ($phoneItem['VALUE'] === $newData['phone']) { + $phoneExists = true; + break; + } + } + if (!$phoneExists) { + $updateFields['PHONE'] = [['VALUE' => $newData['phone'], 'VALUE_TYPE' => 'MOBILE']]; + } + } + + // Обновляем email, если он изменился + if (isset($newData['email'])) { + $emailExists = false; + foreach ($contact['EMAIL'] ?? [] as $emailItem) { + if ($emailItem['VALUE'] === $newData['email']) { + $emailExists = true; + break; + } + } + if (!$emailExists) { + $updateFields['EMAIL'] = [['VALUE' => $newData['email'], 'VALUE_TYPE' => 'WORK']]; + } + } + + // Обновляем Telegram, если он изменился + if (!empty($tg_username) && !imExists($contact['IM'] ?? [], $tg_username)) { + $updateFields['IM'][] = [ + 'VALUE' => $tg_username, + 'VALUE_TYPE' => 'TELEGRAM', + 'TYPE_ID' => 'TELEGRAM' + ]; + } + + if (empty($updateFields)) { + return ['success' => true, 'message' => 'Нет изменений для обновления']; + } + + // Отправляем обновление в Bitrix24 + $updateResponse = b24_request('crm.contact.update', [ + 'id' => $contactId, + 'fields' => $updateFields + ]); + + if (!empty($updateResponse['error'])) { + return ['success' => false, 'error' => 'Ошибка обновления: '.$updateResponse['error']]; + } + + return ['success' => true, 'contact_id' => $contactId]; + } + } class zohoHandler extends FormHandler { @@ -34,43 +396,6 @@ class zohoHandler extends FormHandler { } } -// class mindboxHandler extends FormHandler { -// public function handle($data) { -// // Отправка в стандартный обработчик (например, email) -// error_log("Отправка в mindBox: " . json_encode($data)); -// // if (is_string($data)) { -// // parse_str($data, $parsedData); // Преобразуем строку в массив -// // $data = $parsedData; -// // } - -// // $url = 'https://api.mindbox.ru/v3/operations/async?endpointId=cosmopet.Website&operation=DobavleniePolzovatelyaSSajta'; - -// // $data = array( -// // "email" => $data['email'], -// // "subscriptions" => array( -// // array( -// // "pointOfContact"=> "Email" -// // ), -// // ), -// // ); - -// // $data_string = json_encode(array("customer" =>$data)); - -// // $ch = curl_init($url); - -// // curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string); - -// // curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json')); - -// // curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - -// // $result = curl_exec($ch); - -// // curl_close($ch); -// return parent::handle($data); -// } -// } class emailHandler extends FormHandler { public function handle($data) { @@ -126,4 +451,70 @@ class FormHandlerFactory { } -?> \ No newline at end of file + + +// Пример обработки обновления профиля пользователя +add_action('profile_update', 'handle_profile_update', 10, 2); + + function handle_profile_update($userID, $old_user_data) { + $user = get_user_by('ID', $userID); + + $email = $user->user_email; + $phone = get_user_meta($userID, 'billing_phone', true); + $first_name = get_user_meta($userID, 'first_name', true); + $last_name = get_user_meta($userID, 'last_name', true); + $name = trim($first_name . ' ' . $last_name); + + $newData = [ + 'name' => $name, + 'email' => $email, + 'phone' => $phone, + ]; + + $result = b24_update_contact_by_user_id($userID, $newData); + + if (!$result['success']) { + error_log('Ошибка обновления контакта в Bitrix24: ' . $result['error']); + } + } + + +add_action('woocommerce_thankyou', 'add_b24_tracking_script', 10, 1); + +function add_b24_tracking_script($order_id) { + if (!$order_id) return; + + $order = wc_get_order($order_id); + + echo ''; +} + +function get_utm_data() { + $utm_data = []; + $utm_params = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term']; + + foreach ($utm_params as $param) { + $utm_data[$param] = $_GET[$param] ?? $_COOKIE[$param] ?? ''; + } + + return $utm_data; +} + + +// Функция для сохранения UTM в куки (если нужно хранить между сессиями) +function save_utm_to_cookies() { + $utm_params = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term']; + + foreach ($utm_params as $param) { + if (isset($_GET[$param])) { + setcookie($param, $_GET[$param], time() + 3600 * 24 * 30, '/'); + } + } +} + +save_utm_to_cookies(); \ No newline at end of file