Как программно и автоматически загружать, устанавливать, активировать и заменять плагины WordPress

Опубликовано: 2018-09-18

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

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

Заставить пользователей что-то делать сложно. Так почему бы не загружать, устанавливать и активировать плагины #WordPress автоматически? Требуется всего несколько строк кода.

НАЖМИТЕ, ЧТОБЫ НАПИСАТЬ

Зачем загружать, устанавливать и активировать плагины с помощью кода?

Есть несколько сценариев, но теория в стороне, давайте посмотрим на ситуацию, в которой находится WP Reset. Я уже писал пост о ребрендинге reset-wp в WP Reset. Помимо прочего, этот процесс включает в себя привлечение людей, которые уже используют reset-wp, к удалению его со своих сайтов, а затем к установке WP Reset. Зачем кому-то делать это только потому, что мы попросили? И даже если они захотят это сделать, они будут сопротивляться, потому что это далеко не два клика. Впрочем, если все объяснить и свести к одной кнопке «Да, давай, замени reset-wp на Reset WP», то все выглядит не так уж и плохо.

Не связывайтесь с сайтами людей без их разрешения! Период. Даже если это «крошечная мелочь». Это не круто. Это не ваш сайт. Уведомляйте пользователей о любых изменениях, когда они обновляют плагин или добавляют новые функции.

Из-за правил wp.org, запрещающих нам отслеживать действия пользователей (без их согласия, а мы не хотели беспокоить их вопросами), у меня, к сожалению, нет номеров, которыми можно поделиться. Но что я могу вам сказать, так это то, что у нас не было жалоб от пользователей reset-wp, которые прошли процесс замены или просто увидели уведомление в плагине. И мы занимаемся этим уже более семи недель.

Можно ли это делать? Пользователи будут против?

Пользователи наверняка будут возражать против всего, что вы делаете за их спиной! Не делай этого! Не делайте ничего без разрешения пользователей. Особенно, если плагин размещен на wp.org, потому что это противоречит правилам. Если вы это сделаете, администраторы незамедлительно удалят ваш плагин из репозитория.

Но если вы спросите разрешения — «Можем ли мы заменить плагин А на плагин Б? Пожалуйста подтвердите." Тогда это нормально. Процесс деактивации и удаления одного плагина, а также загрузки и активации другого занимает больше нескольких кликов. Так что, если вам удастся автоматизировать этот процесс и сократить его до одного клика, пользователи будут довольны.

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

Как обычно, требуется очень мало кода

В псевдокоде это общая идея того, что мы хотим сделать:

// pseudo code only!
// DO NOT copy & paste

var $old_plugin;
var $new_plugin;

if ( is_plugin_installed( $new_plugin ) ) {
  // new plugin is already installed
  // make sure we have the last version
  upgrade_plugin( $new_plugin );
} else {
  install_plugin( $new_plugin );
}

if ( !is_plugin_active( $new_plugin ) ) {
  // new plugin is not active - activate it
  activate_plugin( $new_plugin );
}

// deactivate old plugin
deactivate_plugin( $old_plugin );

// if needed delete old plugin
delete_plugin( $old_plugin );

// pseudo code only!
// DO NOT copy & paste

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

Нам нужно несколько функций

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

Важно понять, как WordPress идентифицирует плагин, как он узнает, какой плагин какой. Он делает это с помощью слага плагина — комбинации имени папки плагина и основного файла PHP. Например: привет-долли/привет-долли.php. Основной файл PHP — это файл с заголовками плагина. Чтобы получить слаг, запустите plugin_basename( __FILE__ ) . Всякий раз, когда вам нужно проверить, активен ли плагин или хотите что-то с ним сделать, вам нужно использовать слаг плагина. Этот слаг похож, но не совпадает с слагом с wp.org. В репозитории slug — это просто имя папки без имени файла. Итак, для Hello Dolly это «hello-dolly». В данный момент нам это не нужно, но это необходимо уточнить. Для более подробного ознакомления с этой несколько запутанной темой ознакомьтесь с этой веткой на Stack Exchange.

WordPress идентифицирует плагины по их слагу, т.е. hello-dolly/hello-dolly.php. Чтобы получить слаг, запустите plugin_basename( __FILE__ ) в основном файле плагина.

is_plugin_active( $plugin_slug ) встроен, поэтому нам нечего делать. Страница Кодекса не раскрывает много лишнего, это простая функция.

is_plugin_installed( $plugin_slug ) не является встроенным, но это всего несколько строк кода.

function is_plugin_installed( $slug ) {
  if ( ! function_exists( 'get_plugins' ) ) {
    require_once ABSPATH . 'wp-admin/includes/plugin.php';
  }
  $all_plugins = get_plugins();
  
  if ( !empty( $all_plugins[$slug] ) ) {
    return true;
  } else {
    return false;
  }
}

Это все условные функции тестирования, которые нам нужны. Теперь о тех, кто что-то делает. activate_plugin( ) является встроенным и имеет четыре параметра, так что загляните на страницу Codex об этом.

deactivate_plugins( $plugin_slug ) также доступен из коробки, но обязательно обратите внимание на «s» (во множественном числе) в имени функции. У него тоже есть несколько параметров, так что прочитайте страницу Кодекса.

install_plugin( $plugin_zip ) доступен как часть класса Plugin_Upgrader . Нет необходимости в каком-либо дополнительном коде, просто новый экземпляр класса. То же самое касается upgrade_plugin( $plugin_slug ) .

function install_plugin( $plugin_zip ) {
  include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
  wp_cache_flush();

  $upgrader = new Plugin_Upgrader();
  $installed = $upgrader->install( $plugin_zip );

  return $installed;
}

function upgrade_plugin( $plugin_slug ) {
  include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
  wp_cache_flush();

  $upgrader = new Plugin_Upgrader();
  $upgraded = $upgrader->upgrade( $plugin_slug );

  return $upgraded;
}

wp_cache_flush() может и не нужен, но я добавил его на всякий случай. Помимо того, что запуск выполняется на 10 мс дольше, это не может причинить никакого вреда.

Собираем все вместе

Если вы читаете эту статью не из любопытства, а из-за реальной необходимости реализовать код в плагине, я настоятельно рекомендую установить плагин reset-wp. Читать о коде приятно, но ничто не сравнится с тестированием в реальных условиях.

Я предпочитаю использовать admin_action почти для всего, что не требует полноценного графического интерфейса администратора. Итак, добавьте это в функцию, где добавляются другие действия и фильтры: add_action( 'admin_action_replace_plugin', 'replace_plugin' ); . Когда пользователь откроет admin.php?action=replace_plugin, наш код запустится. Пожалуйста, не жестко кодируйте этот URL. Используйте что-то вроде: $url = add_query_arg(array('action' => 'replace_plugin'), admin_url('admin.php')); . Это говорит о качестве вашего кода.

Вот код, который вы можете скопировать/вставить. Очевидно, измените три переменные сверху с вашими значениями.

function replace_plugin() {
  // modify these variables with your new/old plugin values
  $plugin_slug = 'wp-reset/wp-reset.php';
  $plugin_zip = 'https://downloads.wordpress.org/plugin/wp-reset.latest-stable.zip';
  $old_plugin_slug = 'reset-wp/reset-wp.php';
  
  echo 'If things are not done in a minute <a href="plugins.php">click here to return to Plugins page</a><br><br>';
  echo 'Starting ...<br><br>';
  
  echo 'Check if new plugin is already installed - ';
  if ( is_plugin_installed( $plugin_slug ) ) {
    echo 'it\'s installed! Making sure it\'s the latest version.';
    upgrade_plugin( $plugin_slug );
    $installed = true;
  } else {
    echo 'it\'s not installed. Installing.';
    $installed = install_plugin( $plugin_zip );
  }
  
  if ( !is_wp_error( $installed ) && $installed ) {
    echo 'Activating new plugin.';
    $activate = activate_plugin( $plugin_slug );
    
    if ( is_null($activate) ) {
      echo '<br>Deactivating old plugin.<br>';
      deactivate_plugins( array( $old_plugin_slug ) );
      
      echo '<br>Done! Everything went smooth.';
    }
  } else {
    echo 'Could not install the new plugin.';
  }
}
  
function is_plugin_installed( $slug ) {
  if ( ! function_exists( 'get_plugins' ) ) {
    require_once ABSPATH . 'wp-admin/includes/plugin.php';
  }
  $all_plugins = get_plugins();
  
  if ( !empty( $all_plugins[$slug] ) ) {
    return true;
  } else {
    return false;
  }
}

function install_plugin( $plugin_zip ) {
  include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
  wp_cache_flush();
  
  $upgrader = new Plugin_Upgrader();
  $installed = $upgrader->install( $plugin_zip );

  return $installed;
}

function upgrade_plugin( $plugin_slug ) {
  include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
  wp_cache_flush();
  
  $upgrader = new Plugin_Upgrader();
  $upgraded = $upgrader->upgrade( $plugin_slug );

  return $upgraded;
}

В коде используется все, что мы уже обсуждали. Графический интерфейс и сообщения очень просты, поэтому добавьте немного CSS или загрузите URL-адрес в лайтбокс, как мы сделали в reset-wp.

Автоматическое выполнение скучных рутинных задач для пользователей всегда является огромным плюсом для #UX. Узнайте, как легко загрузить, установить и активировать несколько плагинов #WordPress одним щелчком мыши.

НАЖМИТЕ, ЧТОБЫ НАПИСАТЬ

Один щелчок всегда лучше, чем десять

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

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