Andrei | отправка форм и заказов в TG

pull/36/head
parent 13626b84a1
commit 9c447b5020
  1. 8
      wp-content/themes/cosmopet/modules/forms/assets/js/form.js
  2. 112
      wp-content/themes/cosmopet/modules/forms/module-ajax-controller.php
  3. 195
      wp-content/themes/cosmopet/modules/forms/module-controller.php
  4. 92
      wp-content/themes/cosmopet/modules/shop/components/checkout/assets/js/script.js
  5. 11
      wp-content/themes/cosmopet/templates/footer.twig
  6. 1
      wp-content/themes/cosmopet/templates/forms/discount.twig
  7. 8
      wp-content/themes/cosmopet/templates/forms/footer-form.twig
  8. 5
      wp-content/themes/cosmopet/templates/modal/to_know.twig

@ -76,12 +76,16 @@ jQuery(document).ready(function($) {
$('.modal__form-sub').on('submit', function (e) {
e.preventDefault();
var action = $(this).attr('action')
var email = $(this).find('input[name="email"]').val()
var data = $(this).serialize()
var formData = $(this).serialize()
$.ajax({
type: 'post',
url: woocommerce_params.ajax_url,
data: data,
data: {
action: action,
formData: formData
},
beforeSend: function (response) {
},

@ -3,33 +3,33 @@
require_once 'module-controller.php';
add_action('wp_ajax_contact_form', function() {
$enabledHandlers = ['b24', 'email'];
$enabledHandlers = ['b24', 'email', 'tg'];
process_form($enabledHandlers);
});
add_action('wp_ajax_nopriv_contact_form', function() {
$enabledHandlers = ['b24', 'email'];
$enabledHandlers = ['b24', 'email', 'tg'];
process_form($enabledHandlers);
});
add_action('wp_ajax_subscribe_form', function() {
$enabledHandlers = ['b24', 'email'];
$enabledHandlers = ['b24', 'email', 'tg'];
process_form($enabledHandlers);
});
add_action('wp_ajax_nopriv_subscribe_form', function() {
$enabledHandlers = ['b24', 'email'];
$enabledHandlers = ['b24', 'email', 'tg'];
process_form($enabledHandlers);
});
add_action('wp_ajax_to_know_form', function() {
$enabledHandlers = ['b24'];
$enabledHandlers = ['b24', 'tg'];
process_form($enabledHandlers);
});
add_action('wp_ajax_nopriv_to_know_form', function() {
$enabledHandlers = ['b24'];
$enabledHandlers = ['b24', 'tg'];
process_form($enabledHandlers);
});
@ -42,4 +42,104 @@ function process_form($enabledHandlers) {
}
add_action('woocommerce_thankyou', 'send_order_data_on_payment', 10, 1);
function send_order_data_on_payment($order_id) {
$order = wc_get_order($order_id);
$already_sent = $order->get_meta('_order_sent');
if (!$already_sent) {
// Отправляем заказ в Bitrix24
send_order_data($order_id);
// Помечаем заказ как отправленный, чтобы избежать дублирования
$order->update_meta_data('_order_sent', '1');
$order->save();
}
}
function send_order_data($order_id) {
$order = wc_get_order($order_id);
// 1. Получаем данные заказа
$customer_name = $order->get_billing_first_name() . ' ' . $order->get_billing_last_name();
$customer_phone = $order->get_billing_phone();
$customer_email = $order->get_billing_email();
$order_total = $order->get_total();
$order_comment = '';
$utm = get_utm_data()['utm_source'];
$url = '';
$fName = 2;
// 2. Формируем список товаров
foreach ($order->get_items() as $item) {
$product = $item->get_product();
$order_comment .= sprintf(
"%s x %s = %s\n",
$product->get_name(),
$item->get_quantity(),
wc_price($item->get_total())
);
}
$order_comment .= "\n=== ДАННЫЕ ДОСТАВКИ ===\n";
$order_comment .= "Город: " . $order->get_billing_city() . "\n";
$order_comment .= "Адрес: " . $order->get_billing_address_1() . "\n";
if ($order->get_billing_address_2()) {
$order_comment .= "Доп. адрес: " . $order->get_billing_address_2() . "\n";
}
$order_comment .= "Способ доставки: " . $order->get_shipping_method() . "\n";
$order_comment .= "Комментарий к заказу: " . $order->get_customer_note() . "\n";
if (is_user_logged_in()) {
$user_id = get_current_user_id();
}
else{
$user_id = '';
}
$form_title = 'Покупка на сайте';
$formData = [
// Основные данные
'TITLE' => 'Заказ #' . $order_id,
'NAME' => $customer_name,
'PHONE' => $customer_phone,
'EMAIL' => $customer_email,
'USER_ID' => $user_id,
'ORDER_ID' => $order_id,
'ORDER_TOTAL' => $order_total,
'PAYMENT_METHOD' => $order->get_payment_method_title(),
'COMMENTS' => $order_comment,
// Адрес (префикс ADDR_)
'ADDR_CITY' => $order->get_billing_city(),
'ADDR_STREET' => $order->get_billing_address_1(),
'ADDR_STREET2' => $order->get_billing_address_2(),
// UTM-метки (префикс UTM_)
'UTM_SOURCE' => $utm,
'UTM_MEDIUM' => get_utm_data()['utm_medium'] ?? '',
'UTM_CAMPAIGN' => get_utm_data()['utm_campaign'] ?? '',
// Системные поля
'SOURCE' => 'WooCommerce',
'FNAME' => $fName,
];
// Добавляем товары (префикс PRODUCT_1_, PRODUCT_2_ и т.д.)
$product_index = 1;
foreach ($order->get_items() as $item) {
$product = $item->get_product();
$formData["PRODUCT_{$product_index}_NAME"] = $product->get_name();
$formData["PRODUCT_{$product_index}_QTY"] = $item->get_quantity();
$formData["PRODUCT_{$product_index}_PRICE"] = $item->get_total();
$formData["PRODUCT_{$product_index}_SKU"] = $product->get_sku();
$product_index++;
}
$handler = FormHandlerFactory::getHandler(['tg']);
$response = $handler->handle($formData);
}
?>

@ -13,12 +13,29 @@ abstract class FormHandler {
}
return ['success' => true, 'message' => 'Форма обработана'];
}
public function formatData($data) {
if (is_string($data)) {
parse_str($data, $parsedData); // Преобразуем строку в массив
$data = $parsedData;
}
$formattedMessage = "Данные формы:\n\n";
// Проходим по всем полям данных и добавляем их в сообщение
foreach ($data as $key => $value) {
$formattedMessage .= sprintf("%s: %s\n", $key, $value);
}
return $formattedMessage;
}
}
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
error_log("Отправка в b24: " . json_encode($data));
@ -27,8 +44,6 @@ 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;
@ -197,7 +212,6 @@ function valueExists($items, $value) {
return false;
}
/* Функция POST-запроса к API Bitrix24 по адреcу Веб-хука */
function b24_request($method, $params = []) {
$url = WEBHOOK_URL . $method; // ТУТ ВСТАВЛЯЕМ ХУК ОТ ИНТЕГРАТОРА
$curl = curl_init();
@ -238,15 +252,12 @@ function b24_send_lead($contactId, $msg, $stage, $fName, $order_total, $method,
'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,
]
@ -255,10 +266,14 @@ function b24_send_lead($contactId, $msg, $stage, $fName, $order_total, $method,
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'])) {
@ -267,7 +282,6 @@ function b24_send_lead($contactId, $msg, $stage, $fName, $order_total, $method,
$error = 'Ошибка создания сделки';
}
// Возвращаем результат
return [
'success' => empty($error),
'contact_id' => $contactId,
@ -282,28 +296,27 @@ function b24_send_lead($contactId, $msg, $stage, $fName, $order_total, $method,
];
}
// Function to add lead (wraps b24_get_or_create_contact and b24_send_lead)
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);
$contact = $this->b24_get_or_create_contact($phone, $name, $email, $utm, $userID, $isSubscribe);
if (!empty($contact['contact_id'])) {
$contactId = $contact['contact_id'];
}
else{
} else {
return ['error' => $contact['error']];
}
$msg = $msg . '
Отправлено со страницы: ' . $url;
b24_send_lead($contactId, $msg, $stage, $fName, $order_total, $method, $form_title, $order_id);
$msg = $msg . "\nОтправлено со страницы: " . $url;
return $this->b24_send_lead($contactId, $msg, $stage, $fName, $order_total, $method, $form_title, $order_id);
}
// Function to update contact based on userID
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' => 'Пользователь не найден'];
@ -326,12 +339,12 @@ function b24_send_lead($contactId, $msg, $stage, $fName, $order_total, $method,
$contactId = $contact['ID'];
$updateFields = [];
// Обновляем имя, если оно изменилось
// Update name if changed
if (isset($newData['name']) && $newData['name'] !== $contact['NAME']) {
$updateFields['NAME'] = $newData['name'];
}
// Обновляем телефон, если он изменился
// Update phone if changed
if (isset($newData['phone'])) {
$phoneExists = false;
foreach ($contact['PHONE'] ?? [] as $phoneItem) {
@ -345,7 +358,7 @@ function b24_send_lead($contactId, $msg, $stage, $fName, $order_total, $method,
}
}
// Обновляем email, если он изменился
// Update email if changed
if (isset($newData['email'])) {
$emailExists = false;
foreach ($contact['EMAIL'] ?? [] as $emailItem) {
@ -359,7 +372,7 @@ function b24_send_lead($contactId, $msg, $stage, $fName, $order_total, $method,
}
}
// Обновляем Telegram, если он изменился
// Update Telegram if changed
if (!empty($tg_username) && !imExists($contact['IM'] ?? [], $tg_username)) {
$updateFields['IM'][] = [
'VALUE' => $tg_username,
@ -372,7 +385,7 @@ function b24_send_lead($contactId, $msg, $stage, $fName, $order_total, $method,
return ['success' => true, 'message' => 'Нет изменений для обновления'];
}
// Отправляем обновление в Bitrix24
// Send update request
$updateResponse = b24_request('crm.contact.update', [
'id' => $contactId,
'fields' => $updateFields
@ -384,7 +397,6 @@ function b24_send_lead($contactId, $msg, $stage, $fName, $order_total, $method,
return ['success' => true, 'contact_id' => $contactId];
}
}
class zohoHandler extends FormHandler {
@ -396,6 +408,62 @@ class zohoHandler extends FormHandler {
}
}
class tgHandler extends FormHandler {
public function handle($data) {
global $site_env;
if ($site_env->site_region == 'ru'){
$botToken = '7689949404:AAHLTKmopffoNkndHJt-rOmAIZ7Hb6aKf80';
$chatId = '-1002591296904';
}
else if ($site_env->site_region == 'ae'){
$botToken = '7589204557:AAHh2qa5mUwRBq4fUyjQzqARpk4jDfUu5Yc';
$chatId = '-1002537433508';
}
// Форматируем данные для отправки в Telegram
$message = strip_tags($this->formatData($data));
// Отправляем сообщение в Telegram
$this->sendToTelegram($botToken, $chatId, $message);
// Вызываем следующий обработчик в цепочке
return parent::handle($data);
}
// Функция для отправки данных в Telegram
private function sendToTelegram($botToken, $chatId, $message) {
$url = "https://api.telegram.org/bot$botToken/sendMessage";
$maxLength = 4096;
// Разбиваем сообщение на части, если оно длиннее лимита
$messages = str_split($message, $maxLength);
foreach ($messages as $msgPart) {
$data = [
'chat_id' => $chatId,
'text' => $msgPart,
'parse_mode' => 'HTML',
];
$options = [
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
'content' => http_build_query($data),
],
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
// Логируем HTTP-код и тело ответа
$httpCode = isset($http_response_header[0]) ? $http_response_header[0] : 'No HTTP response';
}
}
}
class emailHandler extends FormHandler {
public function handle($data) {
@ -412,21 +480,6 @@ class emailHandler extends FormHandler {
// Вызываем следующий обработчик в цепочке
return parent::handle($data);
}
private function formatData($data) {
if (is_string($data)) {
parse_str($data, $parsedData); // Преобразуем строку в массив
$data = $parsedData;
}
$formattedMessage = "Данные формы:\n\n";
// Проходим по всем полям данных и добавляем их в сообщение
foreach ($data as $key => $value) {
$formattedMessage .= sprintf("%s: %s\n", $key, $value);
}
return $formattedMessage;
}
}
class FormHandlerFactory {
@ -438,14 +491,12 @@ class FormHandlerFactory {
if (in_array('zoho', $enabledHandlers)) {
$handler = new zohoHandler($handler);
}
// if (in_array('mindbox', $enabledHandlers)) {
// $handler = new mindboxHandler($handler);
// }
if (in_array('tg', $enabledHandlers)) {
$handler = new tgHandler($handler);
}
if (in_array('b24', $enabledHandlers)) {
$handler = new b24Handler($handler);
}
return $handler ?: new DefaultHandler();
}
}
@ -453,46 +504,46 @@ class FormHandlerFactory {
// Пример обработки обновления профиля пользователя
add_action('profile_update', 'handle_profile_update', 10, 2);
// // Пример обработки обновления профиля пользователя
// add_action('profile_update', 'handle_profile_update', 10, 2);
function handle_profile_update($userID, $old_user_data) {
$user = get_user_by('ID', $userID);
// 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);
// $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,
];
// $newData = [
// 'name' => $name,
// 'email' => $email,
// 'phone' => $phone,
// ];
$result = b24_update_contact_by_user_id($userID, $newData);
// $result = b24_update_contact_by_user_id($userID, $newData);
if (!$result['success']) {
error_log('Ошибка обновления контакта в Bitrix24: ' . $result['error']);
}
}
// if (!$result['success']) {
// error_log('Ошибка обновления контакта в Bitrix24: ' . $result['error']);
// }
// }
add_action('woocommerce_thankyou', 'add_b24_tracking_script', 10, 1);
// add_action('woocommerce_thankyou', 'add_b24_tracking_script', 10, 1);
function add_b24_tracking_script($order_id) {
if (!$order_id) return;
// function add_b24_tracking_script($order_id) {
// if (!$order_id) return;
$order = wc_get_order($order_id);
// $order = wc_get_order($order_id);
echo '<script>
(window.b24order = window.b24order || []).push({
id: "' . $order_id . '",
sum: "' . $order->get_total() . '"
});
</script>';
}
// echo '<script>
// (window.b24order = window.b24order || []).push({
// id: "' . $order_id . '",
// sum: "' . $order->get_total() . '"
// });
// </script>';
// }
function get_utm_data() {
$utm_data = [];

@ -140,49 +140,49 @@ jQuery(document).ready(function($) {
});
});
jQuery(document).ready(function ($) {
$(document.body).on('checkout_error', function () {
$('.form-input__error').removeClass('active');
$('.woocommerce-error li').each(function () {
var errorMessage = $(this).text().trim();
var fieldKey = $(this).data('id');
if (fieldKey) {
var errorContainer = $('#' + fieldKey + '-error');
if (errorContainer.length) {
errorContainer.html('<span class="error-message">' + errorMessage + '</span>');
$('#' + fieldKey + '-error').addClass('active');
}
}
if (errorMessage == 'phone_err' || errorMessage == 'The string supplied did not seem to be a phone number.' || errorMessage.includes('Некорректный номер телефона')) {
$('#billing_phone-error').html(currentTranslations.phone_number_error).addClass('active'); // Using translated string
}
if (errorMessage == 'Order pickup point not selected.' || errorMessage == 'Не выбран ПВЗ для доставки заказа.') {
$('#pvz-error').html(currentTranslations.shipping_method_error).addClass('active'); // Using translated string
}
if (errorMessage == 'adress_error') {
$('#adr-error').html(currentTranslations.shipping_address_error).addClass('active'); // Using translated string
}
if (errorMessage == 'Неверный адрес эл. почты для выставления счета') {
$('#billing_email-error').html(errorMessage).addClass('active');
}
if (errorMessage == 'Не выбран метод доставки. Пожалуйста перепроверьте ваш адрес или обратитесь за помощью к администрации сайта.') {
$('#billing_city-error').html(errorMessage).addClass('active');
}
if (errorMessage == 'Этот email уже зарегистрирован.') {
$('#acc-error').html(currentTranslations.email_taken_error).addClass('active'); // Using translated string
}
});
});
$('#delete_coupon').on('click', function(){
$('.woocommerce-remove-coupon[data-coupon=' + $(this).data('coupon') + ']').click();
$('#promo_form').show();
$('#promo_delete').hide();
});
$('.woocommerce-remove-coupon').on('click', function(){
$('#promo_form').show();
$('#promo_delete').hide();
});
});
// jQuery(document).ready(function ($) {
// $(document.body).on('checkout_error', function () {
// $('.form-input__error').removeClass('active');
// $('.woocommerce-error li').each(function () {
// var errorMessage = $(this).text().trim();
// var fieldKey = $(this).data('id');
// if (fieldKey) {
// var errorContainer = $('#' + fieldKey + '-error');
// if (errorContainer.length) {
// errorContainer.html('<span class="error-message">' + errorMessage + '</span>');
// $('#' + fieldKey + '-error').addClass('active');
// }
// }
// if (errorMessage == 'phone_err' || errorMessage == 'The string supplied did not seem to be a phone number.' || errorMessage.includes('Некорректный номер телефона')) {
// $('#billing_phone-error').html(currentTranslations.phone_number_error).addClass('active'); // Using translated string
// }
// if (errorMessage == 'Order pickup point not selected.' || errorMessage == 'Не выбран ПВЗ для доставки заказа.') {
// $('#pvz-error').html(currentTranslations.shipping_method_error).addClass('active'); // Using translated string
// }
// if (errorMessage == 'adress_error') {
// $('#adr-error').html(currentTranslations.shipping_address_error).addClass('active'); // Using translated string
// }
// if (errorMessage == 'Неверный адрес эл. почты для выставления счета') {
// $('#billing_email-error').html(errorMessage).addClass('active');
// }
// if (errorMessage == 'Не выбран метод доставки. Пожалуйста перепроверьте ваш адрес или обратитесь за помощью к администрации сайта.') {
// $('#billing_city-error').html(errorMessage).addClass('active');
// }
// if (errorMessage == 'Этот email уже зарегистрирован.') {
// $('#acc-error').html(currentTranslations.email_taken_error).addClass('active'); // Using translated string
// }
// });
// });
// $('#delete_coupon').on('click', function(){
// $('.woocommerce-remove-coupon[data-coupon=' + $(this).data('coupon') + ']').click();
// $('#promo_form').show();
// $('#promo_delete').hide();
// });
// $('.woocommerce-remove-coupon').on('click', function(){
// $('#promo_form').show();
// $('#promo_delete').hide();
// });
// });

@ -33,15 +33,8 @@
<a href="/terms-conditions/" class="footer-about__text">Terms and Conditions</a>
</div>
</div>
<form class="footer-contact form-process" action="contact_form">
<h3 class="footer-contact__title">Want to partner?</h3>
<input name="name" type="text" placeholder="{{ function('pll_e', 'Ваше имя') }}" class="form-inp">
<input name="email" type="email" placeholder="{{ function('pll_e', 'Эл.почта') }}" class="form-inp">
<textarea name="message" class="form-textarea" name="" placeholder="{{ function('pll_e', 'Текст обращения') }}" id=""></textarea>
<input type="hidden" name="from_url" value="{{ current_url }}">
<input type="hidden" name="form_name" value="Contact form in footer">
<button class="footer-contact__submit" type="submit">{{ function('pll_e', 'SUBMIT') }}</button>
</form>
{% include 'forms/footer-form.twig' %}
{% elseif site_region == 'ru' %}

@ -37,7 +37,6 @@
<img src="/wp-content/themes/cosmopet/static/img/discount-line-w.svg">
{% endif %}
<input type="hidden" name="from_url" value="{{ current_url }}">
<input type="hidden" name="form_name" value="Subscribtion form">
<button class="discount_form-btn main_link" type="submit">{{ function('pll_e', 'подписаться') }}</button>
</div>

@ -0,0 +1,8 @@
<form class="footer-contact form-process" action="contact_form">
<h3 class="footer-contact__title">Want to partner?</h3>
<input name="name" type="text" placeholder="{{ function('pll_e', 'Ваше имя') }}" class="form-inp">
<input name="email" type="email" placeholder="{{ function('pll_e', 'Эл.почта') }}" class="form-inp">
<textarea name="message" class="form-textarea" name="" placeholder="{{ function('pll_e', 'Текст обращения') }}" id=""></textarea>
<input type="hidden" name="form_name" value="Contact form in footer">
<button class="footer-contact__submit" type="submit">{{ function('pll_e', 'SUBMIT') }}</button>
</form>

@ -8,15 +8,14 @@
{{ fn ('pll_e', 'Оставьте свой e-mail, и мы оповестим вас, когда продукт появится') }}
</p>
<form action="" class="modal__form-sub">
<form action="to_know_form" class="modal__form-sub">
<div class="label">
<label for="mail" class="label__title">
{{ fn ('pll_e', 'mail') }}
</label>
</div>
<input type="hidden" name="sub_product" value="" id="sub_product_name">
<input type="hidden" name="action" value="to_know_form">
<input type="text" class="form__input" id="mail" placeholder="Email">
<input type="email" required name="email" class="form__input" id="mail" placeholder="Email">
<div class="checkbox checkbox--small active">
<div class="checkbox__state"></div>
<input type="checkbox" name="" checked id="" class="checkbox__input">

Loading…
Cancel
Save