Plugin Directory

Changeset 3384697


Ignore:
Timestamp:
10/26/2025 10:40:37 AM (5 months ago)
Author:
hugeprofit
Message:

Release version 1.0.8 of HugeProfit plugin

Location:
hugeprofit
Files:
22 added
9 edited

Legend:

Unmodified
Added
Removed
  • hugeprofit/trunk/hugeprofit.php

    r3374428 r3384697  
    33Plugin Name: HugeProfit: Inventory, Profit & Finance – CRM for WooCommerce
    44Description: Manage your products, sales, and customers in WooCommerce using HugeProfit CRM. Warehouse, finance, accounting, analytics, POS — all in one window.
    5 Version: 1.0.7
     5Version: 1.0.8
    66Author: HugeProfit
    77Author URI: https://h-profit.com
     
    802802}
    803803
     804/**
     805 * Проверяет доступность WordPress Cron
     806 *
     807 * @return array Массив с результатами проверки
     808 */
     809function hugeprofit_check_cron_availability() {
     810    $results = array(
     811        'is_available' => true,
     812        'issues' => array(),
     813        'method' => 'standard'
     814    );
     815   
     816    // Проверка 1: Отключен ли WP Cron в конфиге
     817    if (defined('DISABLE_WP_CRON') && DISABLE_WP_CRON) {
     818        $results['is_available'] = false;
     819        $results['issues'][] = 'DISABLE_WP_CRON установлен в true';
     820        $results['method'] = 'alternative';
     821    }
     822   
     823    // // Проверка 2: Может ли сайт делать запросы к самому себе (loopback)
     824    // $test_url = site_url('wp-cron.php');
     825    // $response = wp_remote_post($test_url, array(
     826    //     'timeout' => 5,
     827    //     'blocking' => true,
     828    //     'sslverify' => false,
     829    //     'body' => array('doing_wp_cron' => time())
     830    // ));
     831   
     832    // if (is_wp_error($response)) {
     833    //     $results['is_available'] = false;
     834    //     $results['issues'][] = 'Не удается выполнить loopback запрос: ' . $response->get_error_message();
     835    //     $results['method'] = 'alternative';
     836    // }
     837   
     838    // Проверка 3: Тестируем планирование события
     839    $test_hook = 'hugeprofit_cron_test_' . time();
     840    $scheduled = wp_schedule_single_event(time() + 60, $test_hook);
     841   
     842    if ($scheduled === false) {
     843        $results['issues'][] = 'Не удалось запланировать тестовое событие';
     844    } else {
     845        // Проверяем, действительно ли событие было запланировано
     846        $next_run = wp_next_scheduled($test_hook);
     847        if ($next_run === false) {
     848            $results['is_available'] = false;
     849            $results['issues'][] = 'Событие не сохранилось в планировщике';
     850            $results['method'] = 'alternative';
     851        } else {
     852            // Удаляем тестовое событие
     853            wp_clear_scheduled_hook($test_hook);
     854        }
     855    }
     856   
     857    // Сохраняем результаты проверки
     858    update_option('hugeprofit_cron_check', $results);
     859    update_option('hugeprofit_cron_check_time', time());
     860   
     861    return $results;
     862}
     863
     864/**
     865 * Получает результаты проверки Cron (кэшированные или выполняет новую проверку)
     866 *
     867 * @param bool $force_check Принудительная проверка без использования кэша
     868 * @return array Результаты проверки
     869 */
     870function hugeprofit_get_cron_status($force_check = false) {
     871    $last_check = get_option('hugeprofit_cron_check_time', 0);
     872    $cache_duration = 3600; // Кэш на 1 час
     873   
     874    // Если проверка была недавно и не требуется принудительная проверка, возвращаем кэш
     875    if (!$force_check && (time() - $last_check) < $cache_duration) {
     876        $cached_results = get_option('hugeprofit_cron_check');
     877        if ($cached_results !== false) {
     878            return $cached_results;
     879        }
     880    }
     881   
     882    // Выполняем новую проверку
     883    return hugeprofit_check_cron_availability();
     884}
     885
     886/**
     887 * Определяет, следует ли использовать альтернативный метод вместо WP Cron
     888 *
     889 * @return bool True если нужно использовать альтернативный метод
     890 */
     891function hugeprofit_should_use_alternative_method() {
     892    // Проверяем настройку принудительного использования альтернативного метода
     893    $force_alternative = get_option('hugeprofit_force_alternative_method', 'auto');
     894   
     895    if ($force_alternative === 'yes') {
     896        return true;
     897    } elseif ($force_alternative === 'no') {
     898        return false;
     899    }
     900   
     901    // Режим 'auto' - проверяем доступность крона
     902    $cron_status = hugeprofit_get_cron_status();
     903    return !$cron_status['is_available'];
     904}
     905
    804906// Функция для получения URL с ingwest.net
    805907function hugeprofit_get_crm_url() {
     
    9861088});
    9871089
     1090// AJAX обработчик для проверки статуса WP Cron
     1091add_action('wp_ajax_hugeprofit_check_cron_status', function() {
     1092    check_ajax_referer('hugeprofit_check_cron', 'nonce');
     1093   
     1094    $force_check = isset($_POST['force']) && $_POST['force'] === 'true';
     1095    $cron_status = hugeprofit_get_cron_status($force_check);
     1096   
     1097    wp_send_json_success($cron_status);
     1098});
     1099
     1100// AJAX обработчик для сохранения настройки метода синхронизации
     1101add_action('wp_ajax_hugeprofit_save_sync_method', function() {
     1102    check_ajax_referer('hugeprofit_save_sync_method', 'nonce');
     1103   
     1104    if (!current_user_can('manage_options')) {
     1105        wp_send_json_error(__('Insufficient permissions', 'hugeprofit'));
     1106        return;
     1107    }
     1108   
     1109    $method = isset($_POST['method']) ? sanitize_text_field(wp_unslash($_POST['method'])) : 'auto';
     1110   
     1111    // Валидируем значение
     1112    if (!in_array($method, array('auto', 'yes', 'no'), true)) {
     1113        wp_send_json_error(__('Invalid method value', 'hugeprofit'));
     1114        return;
     1115    }
     1116   
     1117    update_option('hugeprofit_force_alternative_method', $method);
     1118   
     1119    wp_send_json_success(array(
     1120        'message' => __('Sync method saved successfully', 'hugeprofit'),
     1121        'method' => $method
     1122    ));
     1123});
     1124
    9881125// === Добавляем поле "Себестоимость товара" в карточку товара WooCommerce ===
    9891126add_action('woocommerce_product_options_general_product_data', function() {
  • hugeprofit/trunk/js/admin-settings.js

    r3366673 r3384697  
    158158               
    159159                $('#hugeprofit-sync-progress-bar').css('width', percentage + '%');
    160                 $('#hugeprofit-sync-message').text(
    161                     hugeprofitSettings.strings.syncProgress + ' ' +
    162                     progress + ' ' + hugeprofitSettings.strings.syncOf + ' ' +
    163                     total
    164                 );
     160               
     161                // Если total == 0, показываем сообщение об инициализации
     162                if (total == 0) {
     163                    $('#hugeprofit-sync-message').text(hugeprofitSettings.strings.syncStarting);
     164                } else {
     165                    $('#hugeprofit-sync-message').text(
     166                        hugeprofitSettings.strings.syncProgress + ' ' +
     167                        progress + ' ' + hugeprofitSettings.strings.syncOf + ' ' +
     168                        total
     169                    );
     170                }
    165171               
    166172                if (!isCompleted && progress < total && total != 0) {
     
    170176                    }, 1000);
    171177                } else if (!isCompleted && total == 0) {
     178                    // Инициализация - проверяем чаще
    172179                    setTimeout(function() {
    173180                        updateSyncProgress(direction, page + 1);
    174                     }, 3000);
     181                    }, 2000);
    175182                } else if (isCompleted) {
    176183                    // Синхронизация действительно завершена
     
    191198    $('#hugeprofit-edit-integration').on('click', function() {
    192199        $('#hugeprofit-integration-form-container').show();
    193         $(this).hide();
     200        $('#hugeprofit-cron-settings-container').hide();
    194201    });
    195202   
     
    197204    $('#hugeprofit-cancel-edit').on('click', function() {
    198205        $('#hugeprofit-integration-form-container').hide();
    199         $('#hugeprofit-edit-integration').show();
     206    });
     207   
     208    // Отображение/скрытие панели настроек крона
     209    $('#hugeprofit-toggle-cron-settings').on('click', function() {
     210        const button = $(this);
     211        const container = $('#hugeprofit-cron-settings-container');
     212       
     213        if (container.is(':visible')) {
     214            container.slideUp(300);
     215            button.removeClass('button-primary').addClass('button-secondary');
     216        } else {
     217            $('#hugeprofit-integration-form-container').slideUp(300);
     218            container.slideDown(300);
     219            button.removeClass('button-secondary').addClass('button-primary');
     220        }
     221    });
     222   
     223    // Закрытие панели настроек крона
     224    $('#hugeprofit-close-cron-settings').on('click', function() {
     225        $('#hugeprofit-cron-settings-container').slideUp(300);
     226        $('#hugeprofit-toggle-cron-settings').removeClass('button-primary').addClass('button-secondary');
    200227    });
    201228   
     
    361388        });
    362389    }
     390   
     391    // Обработчик кнопки перепроверки WP Cron
     392    $('#hugeprofit-recheck-cron').on('click', function() {
     393        const button = $(this);
     394        const originalText = button.html();
     395       
     396        button.prop('disabled', true);
     397        button.html('<span class="dashicons dashicons-update"></span> ' + hugeprofitSettings.strings.cronCheckInProgress);
     398       
     399        $.post(ajaxurl, {
     400            action: 'hugeprofit_check_cron_status',
     401            force: 'true',
     402            nonce: hugeprofitSettings.nonces.checkCron
     403        }, function(response) {
     404            if (response.success) {
     405                alert(hugeprofitSettings.strings.cronCheckSuccess);
     406                // Перезагружаем страницу для отображения обновленного статуса
     407                location.reload();
     408            } else {
     409                alert(hugeprofitSettings.strings.cronCheckError);
     410                button.prop('disabled', false);
     411                button.html(originalText);
     412            }
     413        }).fail(function() {
     414            alert(hugeprofitSettings.strings.cronCheckError);
     415            button.prop('disabled', false);
     416            button.html(originalText);
     417        });
     418    });
     419   
     420    // Обработчик сохранения метода синхронизации
     421    $('#hugeprofit-save-sync-method').on('click', function() {
     422        const button = $(this);
     423        const selectedMethod = $('input[name="sync_method"]:checked').val();
     424        const messageBox = $('#hugeprofit-sync-method-message');
     425       
     426        button.prop('disabled', true);
     427        messageBox.hide();
     428       
     429        $.post(ajaxurl, {
     430            action: 'hugeprofit_save_sync_method',
     431            method: selectedMethod,
     432            nonce: hugeprofitSettings.nonces.saveSyncMethod
     433        }, function(response) {
     434            if (response.success) {
     435                messageBox.html('<div class="notice notice-success inline" style="padding: 10px; margin: 0;"><p>' +
     436                    hugeprofitSettings.strings.syncMethodSaved + '</p></div>');
     437                messageBox.show();
     438               
     439                // Сохраняем состояние открытой панели в localStorage
     440                localStorage.setItem('hugeprofit_cron_settings_open', 'true');
     441               
     442                // Перезагружаем страницу через 1 секунду для отображения нового статуса
     443                setTimeout(function() {
     444                    location.reload();
     445                }, 1000);
     446            } else {
     447                messageBox.html('<div class="notice notice-error inline" style="padding: 10px; margin: 0;"><p>' +
     448                    hugeprofitSettings.strings.syncMethodSaveError + '</p></div>');
     449                messageBox.show();
     450                button.prop('disabled', false);
     451            }
     452        }).fail(function() {
     453            messageBox.html('<div class="notice notice-error inline" style="padding: 10px; margin: 0;"><p>' +
     454                hugeprofitSettings.strings.syncMethodSaveError + '</p></div>');
     455            messageBox.show();
     456            button.prop('disabled', false);
     457        });
     458    });
     459   
     460    // Восстанавливаем состояние панели настроек крона после перезагрузки
     461    if (localStorage.getItem('hugeprofit_cron_settings_open') === 'true') {
     462        $('#hugeprofit-cron-settings-container').show();
     463        $('#hugeprofit-toggle-cron-settings').removeClass('button-secondary').addClass('button-primary');
     464        localStorage.removeItem('hugeprofit_cron_settings_open');
     465    }
    363466});
  • hugeprofit/trunk/languages/hugeprofit-ru_RU.po

    r3368326 r3384697  
    408408msgid "Critical error: "
    409409msgstr "Критическая ошибка: "
     410
     411# Настройки метода синхронизации
     412msgid "Sync method settings"
     413msgstr "Настройки метода синхронизации"
     414
     415msgid "WP Cron status:"
     416msgstr "Статус WP Cron:"
     417
     418msgid "Available"
     419msgstr "Доступен"
     420
     421msgid "Not available"
     422msgstr "Недоступен"
     423
     424msgid "Detected issues:"
     425msgstr "Обнаруженные проблемы:"
     426
     427msgid "Current method:"
     428msgstr "Текущий метод:"
     429
     430msgid "Alternative (AJAX)"
     431msgstr "Альтернативный (AJAX)"
     432
     433msgid "Standard (WP Cron)"
     434msgstr "Стандартный (WP Cron)"
     435
     436msgid "Sync will be performed through AJAX requests. Please keep the page open during synchronization."
     437msgstr "Синхронизация будет выполняться через AJAX запросы. Пожалуйста, не закрывайте страницу во время синхронизации."
     438
     439msgid "Sync will be performed in the background using WP Cron. You can close the page after starting sync."
     440msgstr "Синхронизация будет выполняться в фоновом режиме через WP Cron. Вы можете закрыть страницу после запуска синхронизации."
     441
     442msgid "Recheck WP Cron"
     443msgstr "Перепроверить WP Cron"
     444
     445msgid "Sync method:"
     446msgstr "Метод синхронизации:"
     447
     448msgid "Auto (Recommended)"
     449msgstr "Авто (Рекомендуется)"
     450
     451msgid "Plugin will automatically choose the best method. If WP Cron is available, it will be used. Otherwise, alternative method will be used."
     452msgstr "Плагин автоматически выберет лучший метод. Если WP Cron доступен, он будет использован. В противном случае будет использован альтернативный метод."
     453
     454msgid "Force WP Cron"
     455msgstr "Принудительно WP Cron"
     456
     457msgid "Always use WP Cron for sync (background processing). Select this if you are sure WP Cron works on your hosting."
     458msgstr "Всегда использовать WP Cron для синхронизации (фоновая обработка). Выберите это, если вы уверены, что WP Cron работает на вашем хостинге."
     459
     460msgid "Force Alternative Method"
     461msgstr "Принудительно альтернативный метод"
     462
     463msgid "Always use alternative AJAX method. Select this if WP Cron is blocked on your hosting. Note: page must remain open during sync."
     464msgstr "Всегда использовать альтернативный AJAX метод. Выберите это, если WP Cron заблокирован на вашем хостинге. Примечание: страница должна оставаться открытой во время синхронизации."
     465
     466msgid "Sync started using alternative method. Do not close this page."
     467msgstr "Синхронизация запущена с использованием альтернативного метода. Не закрывайте эту страницу."
     468
     469msgid "Sync started using WP Cron."
     470msgstr "Синхронизация запущена с использованием WP Cron."
     471
     472msgid "Checking WP Cron..."
     473msgstr "Проверка WP Cron..."
     474
     475msgid "WP Cron check completed!"
     476msgstr "Проверка WP Cron завершена!"
     477
     478msgid "An error occurred while checking WP Cron"
     479msgstr "Произошла ошибка при проверке WP Cron"
     480
     481msgid "Sync method saved successfully!"
     482msgstr "Метод синхронизации успешно сохранён!"
     483
     484msgid "An error occurred while saving sync method"
     485msgstr "Произошла ошибка при сохранении метода синхронизации"
     486
     487msgid "Insufficient permissions"
     488msgstr "Недостаточно прав"
     489
     490msgid "Invalid method value"
     491msgstr "Неверное значение метода"
     492
     493msgid "Sync method saved successfully"
     494msgstr "Метод синхронизации успешно сохранён"
  • hugeprofit/trunk/languages/hugeprofit-uk.po

    r3368326 r3384697  
    409409msgstr "Критична помилка: "
    410410
     411# Налаштування методу синхронізації
     412msgid "Sync method settings"
     413msgstr "Налаштування методу синхронізації"
     414
     415msgid "WP Cron status:"
     416msgstr "Статус WP Cron:"
     417
     418msgid "Available"
     419msgstr "Доступний"
     420
     421msgid "Not available"
     422msgstr "Недоступний"
     423
     424msgid "Detected issues:"
     425msgstr "Виявлені проблеми:"
     426
     427msgid "Current method:"
     428msgstr "Поточний метод:"
     429
     430msgid "Alternative (AJAX)"
     431msgstr "Альтернативний (AJAX)"
     432
     433msgid "Standard (WP Cron)"
     434msgstr "Стандартний (WP Cron)"
     435
     436msgid "Sync will be performed through AJAX requests. Please keep the page open during synchronization."
     437msgstr "Синхронізація буде виконуватися через AJAX запити. Будь ласка, не закривайте сторінку під час синхронізації."
     438
     439msgid "Sync will be performed in the background using WP Cron. You can close the page after starting sync."
     440msgstr "Синхронізація буде виконуватися у фоновому режимі через WP Cron. Ви можете закрити сторінку після запуску синхронізації."
     441
     442msgid "Recheck WP Cron"
     443msgstr "Перевірити WP Cron"
     444
     445msgid "Sync method:"
     446msgstr "Метод синхронізації:"
     447
     448msgid "Auto (Recommended)"
     449msgstr "Авто (Рекомендовано)"
     450
     451msgid "Plugin will automatically choose the best method. If WP Cron is available, it will be used. Otherwise, alternative method will be used."
     452msgstr "Плагін автоматично вибере найкращий метод. Якщо WP Cron доступний, він буде використаний. В іншому випадку буде використаний альтернативний метод."
     453
     454msgid "Force WP Cron"
     455msgstr "Примусово WP Cron"
     456
     457msgid "Always use WP Cron for sync (background processing). Select this if you are sure WP Cron works on your hosting."
     458msgstr "Завжди використовувати WP Cron для синхронізації (фонова обробка). Виберіть це, якщо ви впевнені, що WP Cron працює на вашому хостингу."
     459
     460msgid "Force Alternative Method"
     461msgstr "Примусово альтернативний метод"
     462
     463msgid "Always use alternative AJAX method. Select this if WP Cron is blocked on your hosting. Note: page must remain open during sync."
     464msgstr "Завжди використовувати альтернативний AJAX метод. Виберіть це, якщо WP Cron заблокований на вашому хостингу. Примітка: сторінка повинна залишатися відкритою під час синхронізації."
     465
     466msgid "Sync started using alternative method. Do not close this page."
     467msgstr "Синхронізація запущена з використанням альтернативного методу. Не закривайте цю сторінку."
     468
     469msgid "Sync started using WP Cron."
     470msgstr "Синхронізація запущена з використанням WP Cron."
     471
     472msgid "Checking WP Cron..."
     473msgstr "Перевірка WP Cron..."
     474
     475msgid "WP Cron check completed!"
     476msgstr "Перевірка WP Cron завершена!"
     477
     478msgid "An error occurred while checking WP Cron"
     479msgstr "Сталася помилка під час перевірки WP Cron"
     480
     481msgid "Sync method saved successfully!"
     482msgstr "Метод синхронізації успішно збережено!"
     483
     484msgid "An error occurred while saving sync method"
     485msgstr "Сталася помилка під час збереження методу синхронізації"
     486
     487msgid "Insufficient permissions"
     488msgstr "Недостатньо прав"
     489
     490msgid "Invalid method value"
     491msgstr "Невірне значення методу"
     492
     493msgid "Sync method saved successfully"
     494msgstr "Метод синхронізації успішно збережено"
     495
    411496msgid "Log of recent operations"
    412497msgstr "Лог останніх операцій"
  • hugeprofit/trunk/languages/hugeprofit.pot

    r3368326 r3384697  
    408408msgid "Critical error: "
    409409msgstr ""
     410
     411# Sync method settings
     412msgid "Sync method settings"
     413msgstr ""
     414
     415msgid "WP Cron status:"
     416msgstr ""
     417
     418msgid "Available"
     419msgstr ""
     420
     421msgid "Not available"
     422msgstr ""
     423
     424msgid "Detected issues:"
     425msgstr ""
     426
     427msgid "Current method:"
     428msgstr ""
     429
     430msgid "Alternative (AJAX)"
     431msgstr ""
     432
     433msgid "Standard (WP Cron)"
     434msgstr ""
     435
     436msgid "Sync will be performed through AJAX requests. Please keep the page open during synchronization."
     437msgstr ""
     438
     439msgid "Sync will be performed in the background using WP Cron. You can close the page after starting sync."
     440msgstr ""
     441
     442msgid "Recheck WP Cron"
     443msgstr ""
     444
     445msgid "Sync method:"
     446msgstr ""
     447
     448msgid "Auto (Recommended)"
     449msgstr ""
     450
     451msgid "Plugin will automatically choose the best method. If WP Cron is available, it will be used. Otherwise, alternative method will be used."
     452msgstr ""
     453
     454msgid "Force WP Cron"
     455msgstr ""
     456
     457msgid "Always use WP Cron for sync (background processing). Select this if you are sure WP Cron works on your hosting."
     458msgstr ""
     459
     460msgid "Force Alternative Method"
     461msgstr ""
     462
     463msgid "Always use alternative AJAX method. Select this if WP Cron is blocked on your hosting. Note: page must remain open during sync."
     464msgstr ""
     465
     466msgid "Sync started using alternative method. Do not close this page."
     467msgstr ""
     468
     469msgid "Sync started using WP Cron."
     470msgstr ""
     471
     472msgid "Checking WP Cron..."
     473msgstr ""
     474
     475msgid "WP Cron check completed!"
     476msgstr ""
     477
     478msgid "An error occurred while checking WP Cron"
     479msgstr ""
     480
     481msgid "Sync method saved successfully!"
     482msgstr ""
     483
     484msgid "An error occurred while saving sync method"
     485msgstr ""
     486
     487msgid "Insufficient permissions"
     488msgstr ""
     489
     490msgid "Invalid method value"
     491msgstr ""
     492
     493msgid "Sync method saved successfully"
     494msgstr ""
  • hugeprofit/trunk/readme.txt

    r3374428 r3384697  
    66Tested up to: 6.8 
    77Requires PHP: 7.4 
    8 Stable tag: 1.0.7
     8Stable tag: 1.0.8
    99License: GPLv2 or later 
    1010License URI: https://www.gnu.org/licenses/gpl-2.0.html 
  • hugeprofit/trunk/settings.php

    r3374428 r3384697  
    113113        <p><?php echo esc_html__('You can start using all HugeProfit plugin features.', 'hugeprofit'); ?></p>
    114114       
    115         <!-- Кнопка редактирования настроек интеграции -->
    116         <div style="margin-top: 10px;">
     115        <!-- Кнопки управления -->
     116        <div style="margin-top: 10px; display: flex; justify-content: space-between; align-items: center; gap: 10px;">
    117117            <button id="hugeprofit-edit-integration" class="button button-secondary">
    118118                <?php echo esc_html__('Edit integration settings', 'hugeprofit'); ?>
     119            </button>
     120            <button id="hugeprofit-toggle-cron-settings" class="button button-secondary" style="padding: 5px 12px; display: flex; align-items: center;" title="<?php echo esc_attr__('Sync method settings', 'hugeprofit'); ?>">
     121                <span class="dashicons dashicons-admin-generic" style="margin: 0; font-size: 18px;"></span>
    119122            </button>
    120123        </div>
     
    356359            </div>
    357360        </div>
     361       
     362        <!-- Блок настройки метода синхронизации -->
     363        <div id="hugeprofit-cron-settings-container" style="display: none; margin-top: 30px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.05);">
     364            <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;">
     365                <h2 style="margin: 0;"><?php echo esc_html__('Sync method settings', 'hugeprofit'); ?></h2>
     366                <button id="hugeprofit-close-cron-settings" class="button button-secondary" style="padding: 5px 10px;">
     367                    <span class="dashicons dashicons-no" style="margin: 0;"></span>
     368                </button>
     369            </div>
     370           
     371            <?php
     372            // Получаем текущий статус крона
     373            $cron_status = hugeprofit_get_cron_status();
     374            $current_method = get_option('hugeprofit_force_alternative_method', 'auto');
     375            ?>
     376           
     377            <div style="padding: 15px; border-radius: 4px; background: <?php echo $cron_status['is_available'] ? '#e8f5e9' : '#fff3e0'; ?>; margin-bottom: 20px;">
     378                <div style="display: flex; align-items: center; margin-bottom: 10px;">
     379                    <span class="dashicons <?php echo $cron_status['is_available'] ? 'dashicons-yes-alt' : 'dashicons-warning'; ?>" style="color: <?php echo $cron_status['is_available'] ? '#4CAF50' : '#FF9800'; ?>; font-size: 24px; margin-right: 10px;"></span>
     380                    <strong><?php echo esc_html__('WP Cron status:', 'hugeprofit'); ?>
     381                        <span style="color: <?php echo $cron_status['is_available'] ? '#4CAF50' : '#FF9800'; ?>;">
     382                            <?php echo $cron_status['is_available'] ? esc_html__('Available', 'hugeprofit') : esc_html__('Not available', 'hugeprofit'); ?>
     383                        </span>
     384                    </strong>
     385                </div>
     386               
     387                <?php if (!empty($cron_status['issues'])): ?>
     388                <div style="font-size: 13px; color: #666; margin-top: 10px;">
     389                    <strong><?php echo esc_html__('Detected issues:', 'hugeprofit'); ?></strong>
     390                    <ul style="margin: 5px 0; padding-left: 20px;">
     391                        <?php foreach ($cron_status['issues'] as $issue): ?>
     392                        <li><?php echo esc_html($issue); ?></li>
     393                        <?php endforeach; ?>
     394                    </ul>
     395                </div>
     396                <?php endif; ?>
     397               
     398                <div style="margin-top: 15px;">
     399                    <p style="font-size: 13px; color: #666; margin-bottom: 10px;">
     400                        <?php echo esc_html__('Current method:', 'hugeprofit'); ?>
     401                        <strong><?php echo $cron_status['method'] === 'alternative' ? esc_html__('Alternative (AJAX)', 'hugeprofit') : esc_html__('Standard (WP Cron)', 'hugeprofit'); ?></strong>
     402                    </p>
     403                   
     404                    <?php if ($cron_status['method'] === 'alternative'): ?>
     405                    <p style="font-size: 13px; color: #666; background: #fff; padding: 10px; border-radius: 4px; border-left: 3px solid #2196F3;">
     406                        <span class="dashicons dashicons-info" style="color: #2196F3;"></span>
     407                        <?php echo esc_html__('Sync will be performed through AJAX requests. Please keep the page open during synchronization.', 'hugeprofit'); ?>
     408                    </p>
     409                    <?php else: ?>
     410                    <p style="font-size: 13px; color: #666; background: #fff; padding: 10px; border-radius: 4px; border-left: 3px solid #4CAF50;">
     411                        <span class="dashicons dashicons-yes-alt" style="color: #4CAF50;"></span>
     412                        <?php echo esc_html__('Sync will be performed in the background using WP Cron. You can close the page after starting sync.', 'hugeprofit'); ?>
     413                    </p>
     414                    <?php endif; ?>
     415                </div>
     416               
     417                <button id="hugeprofit-recheck-cron" class="button button-secondary" style="margin-top: 10px;">
     418                    <span class="dashicons dashicons-update"></span>
     419                    <?php echo esc_html__('Recheck WP Cron', 'hugeprofit'); ?>
     420                </button>
     421            </div>
     422           
     423            <div style="margin-top: 20px;">
     424                <label style="display: block; margin-bottom: 10px; font-weight: bold;">
     425                    <?php echo esc_html__('Sync method:', 'hugeprofit'); ?>
     426                </label>
     427               
     428                <div style="display: flex; flex-direction: column; gap: 12px;">
     429                    <label style="display: flex; align-items: flex-start; padding: 12px; border: 2px solid #ddd; border-radius: 4px; cursor: pointer;">
     430                        <input type="radio" name="sync_method" value="auto" <?php checked($current_method, 'auto'); ?> style="margin-right: 10px; margin-top: 3px;">
     431                        <div>
     432                            <strong><?php echo esc_html__('Auto (Recommended)', 'hugeprofit'); ?></strong>
     433                            <p style="margin: 5px 0 0 0; font-size: 13px; color: #666;">
     434                                <?php echo esc_html__('Plugin will automatically choose the best method. If WP Cron is available, it will be used. Otherwise, alternative method will be used.', 'hugeprofit'); ?>
     435                            </p>
     436                        </div>
     437                    </label>
     438                   
     439                    <label style="display: flex; align-items: flex-start; padding: 12px; border: 2px solid #ddd; border-radius: 4px; cursor: pointer;">
     440                        <input type="radio" name="sync_method" value="no" <?php checked($current_method, 'no'); ?> style="margin-right: 10px; margin-top: 3px;">
     441                        <div>
     442                            <strong><?php echo esc_html__('Force WP Cron', 'hugeprofit'); ?></strong>
     443                            <p style="margin: 5px 0 0 0; font-size: 13px; color: #666;">
     444                                <?php echo esc_html__('Always use WP Cron for sync (background processing). Select this if you are sure WP Cron works on your hosting.', 'hugeprofit'); ?>
     445                            </p>
     446                        </div>
     447                    </label>
     448                   
     449                    <label style="display: flex; align-items: flex-start; padding: 12px; border: 2px solid #ddd; border-radius: 4px; cursor: pointer;">
     450                        <input type="radio" name="sync_method" value="yes" <?php checked($current_method, 'yes'); ?> style="margin-right: 10px; margin-top: 3px;">
     451                        <div>
     452                            <strong><?php echo esc_html__('Force Alternative Method', 'hugeprofit'); ?></strong>
     453                            <p style="margin: 5px 0 0 0; font-size: 13px; color: #666;">
     454                                <?php echo esc_html__('Always use alternative AJAX method. Select this if WP Cron is blocked on your hosting. Note: page must remain open during sync.', 'hugeprofit'); ?>
     455                            </p>
     456                        </div>
     457                    </label>
     458                </div>
     459               
     460                <button id="hugeprofit-save-sync-method" class="button button-primary" style="margin-top: 15px;">
     461                    <?php echo esc_html__('Save settings', 'hugeprofit'); ?>
     462                </button>
     463               
     464                <div id="hugeprofit-sync-method-message" style="margin-top: 10px; display: none;"></div>
     465            </div>
     466        </div>
     467       
    358468        <?php elseif ($api_token && !$integration_id): ?>
    359469        <?php
     
    496606            'getWcApiKeys' => wp_create_nonce('hugeprofit_get_wc_api_keys'),
    497607            'saveIntegrationId' => wp_create_nonce('hugeprofit_save_integration_id'),
    498             'checkSyncStatus' => wp_create_nonce('hugeprofit_check_sync_status')
     608            'checkSyncStatus' => wp_create_nonce('hugeprofit_check_sync_status'),
     609            'checkCron' => wp_create_nonce('hugeprofit_check_cron'),
     610            'saveSyncMethod' => wp_create_nonce('hugeprofit_save_sync_method')
    499611        ),
    500612        'strings' => array(
     
    518630            'syncCompleted' => __('Synchronization completed successfully!', 'hugeprofit'),
    519631            'syncErrorPrefix' => __('Ошибка: ', 'hugeprofit'),
    520             'syncProgressError' => __('An error occurred while updating progress', 'hugeprofit')
     632            'syncProgressError' => __('An error occurred while updating progress', 'hugeprofit'),
     633            'cronCheckInProgress' => __('Checking WP Cron...', 'hugeprofit'),
     634            'cronCheckSuccess' => __('WP Cron check completed!', 'hugeprofit'),
     635            'cronCheckError' => __('An error occurred while checking WP Cron', 'hugeprofit'),
     636            'syncMethodSaved' => __('Sync method saved successfully!', 'hugeprofit'),
     637            'syncMethodSaveError' => __('An error occurred while saving sync method', 'hugeprofit')
    521638        ),
    522639        'adminUrl' => admin_url('admin.php?page=hugeprofit'),
     
    544661    }
    545662   
     663    // Определяем метод синхронизации
     664    $use_alternative = hugeprofit_should_use_alternative_method();
     665   
    546666    // Сохраняем информацию о текущей синхронизации
    547667    update_option('hugeprofit_sync_in_progress', [
    548668        'direction' => $direction,
    549669        'start_time' => time(),
     670        'last_update' => time(),
    550671        'total' => 0,
    551672        'progress' => 0,
    552673        'page' => 0,
    553         'processed_ids' => []
     674        'processed_ids' => [],
     675        'use_alternative_method' => $use_alternative
    554676    ]);
    555677   
    556     // Запускаем импорт в фоне через WP Cron
    557     if ($direction === 'import') {
    558         wp_schedule_single_event(time(), 'hugeprofit_import_products_batch');
     678    // Запускаем синхронизацию
     679    if ($use_alternative) {
     680        // Альтернативный метод - синхронизация будет выполняться через AJAX запросы
     681        hugeprofit_log("Используется альтернативный метод синхронизации (без WP Cron)");
     682        wp_send_json_success(array(
     683            'method' => 'alternative',
     684            'message' => __('Sync started using alternative method. Do not close this page.', 'hugeprofit')
     685        ));
    559686    } else {
    560         wp_schedule_single_event(time(), 'hugeprofit_export_products_batch');
    561     }
    562    
    563     wp_send_json_success();
     687        // Стандартный метод через WP Cron
     688        hugeprofit_log("Используется стандартный метод синхронизации (WP Cron)");
     689        if ($direction === 'import') {
     690            wp_schedule_single_event(time(), 'hugeprofit_import_products_batch');
     691        } else {
     692            wp_schedule_single_event(time(), 'hugeprofit_export_products_batch');
     693        }
     694       
     695        wp_send_json_success(array(
     696            'method' => 'cron',
     697            'message' => __('Sync started using WP Cron.', 'hugeprofit')
     698        ));
     699    }
    564700});
    565701
     
    577713   
    578714    hugeprofit_log("Запрос прогресса: " . wp_json_encode($sync_info));
     715   
     716    // Если используется альтернативный метод, выполняем работу крона прямо здесь
     717    $use_alternative = isset($sync_info['use_alternative_method']) && $sync_info['use_alternative_method'];
     718   
     719    if ($use_alternative) {
     720        hugeprofit_log("Альтернативный метод: выполняем пакетную обработку напрямую");
     721       
     722        // Проверяем блокировку, чтобы избежать одновременного выполнения
     723        $lock_key = 'hugeprofit_alternative_lock_' . $direction;
     724        $lock_value = get_transient($lock_key);
     725       
     726        if ($lock_value === false) {
     727            // Устанавливаем блокировку на 30 секунд
     728            set_transient($lock_key, time(), 30);
     729           
     730            try {
     731                // Запускаем обработку пакета
     732                if ($direction === 'import') {
     733                    hugeprofit_process_import_batch();
     734                } else {
     735                    hugeprofit_process_export_batch();
     736                }
     737            } catch (Exception $e) {
     738                hugeprofit_log("Ошибка при выполнении альтернативной синхронизации: " . $e->getMessage());
     739            }
     740           
     741            // Снимаем блокировку
     742            delete_transient($lock_key);
     743           
     744            // Обновляем информацию о синхронизации после обработки
     745            $sync_info = get_option('hugeprofit_sync_in_progress', []);
     746        } else {
     747            hugeprofit_log("Альтернативный метод: обработка уже выполняется, пропускаем");
     748        }
     749    }
    579750   
    580751    // Проверяем, запланированы ли еще cron задания для синхронизации
     
    589760            $next_scheduled = wp_next_scheduled('hugeprofit_import_products_batch');
    590761            hugeprofit_log("Следующее запланированное задание импорта: " . ($next_scheduled ? gmdate('Y-m-d H:i:s', $next_scheduled) : 'нет'));
    591             $is_completed = !$next_scheduled && isset($sync_info['progress']) && isset($sync_info['total']) &&
    592                             ($sync_info['progress'] >= $sync_info['total'] || time() - $sync_info['start_time'] > 300);
     762           
     763            // Для альтернативного метода не проверяем next_scheduled
     764            if ($use_alternative) {
     765                $is_completed = isset($sync_info['progress']) && isset($sync_info['total']) &&
     766                                $sync_info['total'] > 0 && $sync_info['progress'] >= $sync_info['total'];
     767            } else {
     768                $is_completed = !$next_scheduled && isset($sync_info['progress']) && isset($sync_info['total']) &&
     769                                ($sync_info['progress'] >= $sync_info['total'] || time() - $sync_info['start_time'] > 300);
     770            }
    593771        } else {
    594772            $next_scheduled = wp_next_scheduled('hugeprofit_export_products_batch');
    595773            hugeprofit_log("Следующее запланированное задание экспорта: " . ($next_scheduled ? gmdate('Y-m-d H:i:s', $next_scheduled) : 'нет'));
    596             $is_completed = !$next_scheduled && isset($sync_info['progress']) && isset($sync_info['total']) &&
    597                             ($sync_info['progress'] >= $sync_info['total'] || time() - $sync_info['start_time'] > 300);
    598         }
    599        
    600         // Дополнительно проверяем, не слишком ли давно было последнее обновление
    601         if (isset($sync_info['last_update']) && time() - $sync_info['last_update'] > 60) {
     774           
     775            // Для альтернативного метода не проверяем next_scheduled
     776            if ($use_alternative) {
     777                $is_completed = isset($sync_info['progress']) && isset($sync_info['total']) &&
     778                                $sync_info['total'] > 0 && $sync_info['progress'] >= $sync_info['total'];
     779            } else {
     780                $is_completed = !$next_scheduled && isset($sync_info['progress']) && isset($sync_info['total']) &&
     781                                ($sync_info['progress'] >= $sync_info['total'] || time() - $sync_info['start_time'] > 300);
     782            }
     783        }
     784       
     785        // Дополнительно проверяем, не слишком ли давно было последнее обновление (только для альтернативного метода)
     786        if ($use_alternative && isset($sync_info['last_update']) && time() - $sync_info['last_update'] > 60) {
    602787            $is_completed = true;
    603788            hugeprofit_log("Синхронизация считается завершенной из-за времени неактивности");
    604         }
    605     }
    606    
    607     // Обновляем время последнего запроса прогресса
    608     $sync_info['last_update'] = time();
    609     update_option('hugeprofit_sync_in_progress', $sync_info);
     789        } elseif (!$use_alternative && isset($sync_info['last_update']) && time() - $sync_info['last_update'] > 60) {
     790            $is_completed = true;
     791            hugeprofit_log("Синхронизация считается завершенной из-за времени неактивности");
     792        }
     793    }
     794   
     795    // НЕ обновляем sync_info здесь, чтобы избежать race condition с процессом синхронизации
     796    // Процесс синхронизации сам управляет своим состоянием и сохраняет прогресс
    610797   
    611798    // Логируем результат проверки
     
    638825            $is_completed = true;
    639826        } else {
    640             // Проверяем, запланированы ли еще cron задания
    641827            $direction = $sync_info['direction'];
    642            
     828            $use_alternative = isset($sync_info['use_alternative_method']) && $sync_info['use_alternative_method'];
     829           
     830            // Примечание: Реальная обработка для альтернативного метода выполняется в hugeprofit_sync_progress
     831            // Здесь мы только проверяем статус для восстановления прогресса при загрузке страницы
     832           
     833            // Проверяем статус (для обоих методов)
    643834            if ($direction === 'import') {
    644835                $next_scheduled = wp_next_scheduled('hugeprofit_import_products_batch');
     
    649840            }
    650841           
    651             // Проверяем метку активного процесса
    652             $import_marker_file = hugeprofit_get_uploads_dir() . '/hugeprofit-import-in-progress.txt';
    653             $export_marker_file = hugeprofit_get_uploads_dir() . '/hugeprofit-export-in-progress.txt';
    654            
    655             if (($direction === 'import' && file_exists($import_marker_file)) ||
    656                 ($direction === 'export' && file_exists($export_marker_file))) {
    657                 $in_progress = true;
     842            // Для альтернативного метода проверяем только время последнего обновления
     843            if ($use_alternative) {
     844                // Если total == 0, значит идет инициализация - считаем процесс активным
     845                if (isset($sync_info['total']) && $sync_info['total'] == 0) {
     846                    // Даем 30 секунд на инициализацию
     847                    $time_elapsed = time() - $sync_info['start_time'];
     848                    $in_progress = isset($sync_info['start_time']) && $time_elapsed < 30;
     849                    hugeprofit_log("Альтернативный метод: инициализация (total=0), прошло {$time_elapsed} сек, in_progress=" . ($in_progress ? 'true' : 'false'));
     850                } else {
     851                    // Если total уже установлен, проверяем время последнего обновления
     852                    $in_progress = isset($sync_info['last_update']) && time() - $sync_info['last_update'] < 60;
     853                    hugeprofit_log("Альтернативный метод: обработка (total={$sync_info['total']}, progress={$sync_info['progress']}), in_progress=" . ($in_progress ? 'true' : 'false'));
     854                }
     855               
     856                // Проверяем, завершен ли прогресс
     857                if (isset($sync_info['progress']) && isset($sync_info['total']) &&
     858                    $sync_info['progress'] >= $sync_info['total'] && $sync_info['total'] > 0) {
     859                    $is_completed = true;
     860                    $in_progress = false;
     861                    hugeprofit_log("Альтернативный метод: синхронизация завершена (progress={$sync_info['progress']}, total={$sync_info['total']})");
     862                }
     863            } else {
     864                // Проверяем метку активного процесса для стандартного метода
     865                $import_marker_file = hugeprofit_get_uploads_dir() . '/hugeprofit-import-in-progress.txt';
     866                $export_marker_file = hugeprofit_get_uploads_dir() . '/hugeprofit-export-in-progress.txt';
     867               
     868                if (($direction === 'import' && file_exists($import_marker_file)) ||
     869                    ($direction === 'export' && file_exists($export_marker_file))) {
     870                    $in_progress = true;
     871                }
    658872            }
    659873           
     
    673887        'direction' => isset($sync_info['direction']) ? $sync_info['direction'] : '',
    674888        'total' => isset($sync_info['total']) ? $sync_info['total'] : 0,
    675         'progress' => isset($sync_info['progress']) ? $sync_info['progress'] : 0
     889        'progress' => isset($sync_info['progress']) ? $sync_info['progress'] : 0,
     890        'use_alternative_method' => isset($sync_info['use_alternative_method']) ? $sync_info['use_alternative_method'] : false
    676891    ]);
    677892});
     
    20242239            $sync_info['progress'] = 0;
    20252240            $sync_info['processed_ids'] = [];
     2241           
     2242            hugeprofit_log("Инициализация: сохраняем sync_info с total=" . $sync_info['total']);
    20262243            update_option('hugeprofit_sync_in_progress', $sync_info);
    20272244           
     
    21832400        $sync_info['progress'] = count($sync_info['processed_ids']);
    21842401        $sync_info['page'] = $page + 1;
     2402       
     2403        hugeprofit_log("Сохраняем sync_info: " . wp_json_encode($sync_info));
    21852404        update_option('hugeprofit_sync_in_progress', $sync_info);
    21862405       
     
    21972416           
    21982417            // Запускаем следующую партию через 10 секунд
    2199             wp_schedule_single_event(time() + 10, 'hugeprofit_export_products_batch');
     2418            wp_schedule_single_event(time() + 3, 'hugeprofit_export_products_batch');
    22002419        } else {
    22012420            hugeprofit_log("Экспорт завершен");
Note: See TracChangeset for help on using the changeset viewer.