обновить_плагины и удалить_временное хранилище

Вопрос или проблема

Я использую этот код, чтобы включить обновление плагина с административной страницы WordPress.

add_filter('plugins_api', 'pud_plugin_info', 20, 3 );
add_filter('update_plugins_my_domain_url', 'pud_update', 10, 4);
add_filter('plugin_auto_update_setting_html', 'pud_plugin_auto_update_setting_html', 10, 3 );
add_action('in_plugin_update_message-plugin-folder/my_plugin.php', 'pud_display_update_message', 10, 2 );


function pud_plugin_auto_update_setting_html($html, $plugin_file, $plugin_data) { 
    if ($plugin_file == 'plugin-folder/my_plugin.php') {
        if(empty($plugin_data['package'])){
            $html = sprintf(__("<span style="color:red;">%s</span>", TEXTDOMAIN), 'Автообновления отключены');
        }
    }
    return $html; 
}

function pud_display_update_message( $plugin_info_array, $plugin_info_object ) {
    if(empty($plugin_info_array['package'])) {
        //нет обновлений
    }
}

function pud_request(){

        $url="my-website-url";

        $response = wp_remote_post($url, array(
            'method' => 'POST',
            'timeout'     => 10,
            'headers' => array('Accept' => 'application/json'),
            'body' => array(
                'token' => $token,
                'plugin' => plugin_id,
                'website' => get_url()
            )
        ));

        if(is_wp_error($response) || 200 !== wp_remote_retrieve_response_code( $response ) || empty( wp_remote_retrieve_body( $response )) ){
            return false;
        }else{
            $remote = json_decode( wp_remote_retrieve_body( $response ) );
        }

        return $remote;

    }

}

function pud_plugin_info( $res, $action, $args ) {

    if('plugin_information' === $action && $args->slug == PLUGIN_SLUG) {
        
        $remote = pud_request();

        if( ! $remote ) {
            return $res;
        }

        $res = new stdClass();

        $res->name = $remote->name;
        $res->slug = $remote->slug;
        $res->version = $remote->version;
        $res->tested = $remote->tested;
        $res->requires = $remote->requires;
        $res->author = $remote->author;
        $res->author_profile = $remote->author_profile;
        $res->download_link = $remote->download_url;
        $res->trunk = $remote->download_url;
        $res->requires_php = $remote->requires_php;
        $res->last_updated = $remote->last_updated;
        $res->package = $remote->package;

        $res->sections = array(
            'description' => $remote->sections->description,
            'installation' => $remote->sections->installation,
            'changelog' => $remote->sections->changelog
        );

        if( ! empty( $remote->banners ) ) {
            $res->banners = array(
                'low' => $remote->banners->low,
                'high' => $remote->banners->high
            );
        }
    }

    return $res;

}

function pud_update($update, $plugin_data, $plugin_file, $locales) {

    $remote = pud_request();

    if($remote
        && (float)PLUGIN_VERSION < (float)$remote->version
        && (float)$remote->requires <= (float)get_bloginfo('version')
        && (float)$remote->requires_php < (float)PHP_VERSION ) {
    
        if($remote->download_url && !empty($remote->download_url)){
            $remote->package = $remote->download_url;
        }

    }

    return $remote;

}

Это работает хорошо, однако, похоже, есть некоторая кэшировка на стороне WordPress (что иногда показывает, что обновления недоступны, даже если я обновляю страницу плагина), и только когда я добавляю этот код, тогда он сразу показывает, что обновления доступны.

add_action('init', function(){
    delete_transient( 'update_plugins' );
    delete_site_transient( 'update_plugins' );
});

Однако использование этого кода, насколько я знаю, не рекомендуется, и я могу заметить, что это значительно замедляет админку WordPress.

Каков лучший способ убедиться, что обновления всегда отображаются и не кэшируются?

Ответ или решение

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

Теория

Транзиенты (Transients) в WordPress – это механизм временного хранения данных в базе данных для улучшения производительности. Они используются для хранения информации, которую периодически необходимо извлекать и обновлять. Например, информация об обновлениях плагинов хранится в полях update_plugins и update_plugins (для мультисайтов). При каждом посещении страницы плагинов WordPress не запрашивает информацию о новых версиях на удалённом сервере, а использует кешированные данные, хранящиеся в этих транзиентах.

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

Примеры

Вы упомянули, что для удаления транзиентов вы используете следующий код:

add_action('init', function(){
    delete_transient('update_plugins');
    delete_site_transient('update_plugins');
});

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

Применение

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

  1. Увеличение интервала проверки обновлений: Вы можете управлять частотой обновлений, изменив периодичность крона. По умолчанию включает в свою работу wp_update_plugins() домашним заданием, его можно настроить через фильтры.

    add_filter('auto_update_plugin', '__return_true');
  2. Ручной запуск обновлений: При необходимости вы можете принудительно вызывать обновление. Это может быть удобно, если администратор хочет моментально получить актуальные обновления, вызывая функцию только при посещении страницы администрирования плагинов.

    function force_check_for_updates() {
        if (is_admin() && current_user_can('update_plugins')) {
            wp_update_plugins();
        }
    }
    add_action('admin_init', 'force_check_for_updates');
  3. Кастомизация через AJAX: Вы можете реализовать механизм, который по запросу будет удалять транзиенты и запускать проверку через AJAX. Это позволит обновлять информацию только по требованию.

    add_action('wp_ajax_refresh_plugin_updates', 'refresh_plugin_updates');
    function refresh_plugin_updates() {
        // Удаляем старые транзиенты
        delete_transient('update_plugins');
        delete_site_transient('update_plugins');
    
        // Запускаем проверку обновлений
        wp_update_plugins();
        wp_send_json_success('Обновления проверены.');
    }

    Затем на стороне клиента можно реализовать кнопку, которая будет запускать эту проверку через AJAX.

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

Учитывая вышеперечисленные методы, вы сможете управлять и улучшать механизм обновлений плагинов с минимальными потерями производительности. Главное – избегать частого удаления транзиентов через init, при этом может помочь более целевой подход к извлечению обновлений.

Оцените материал
Добавить комментарий

Капча загружается...