如何以編程方式和自動下載、安裝、激活和替換 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 上,因為這違反了規則。 如果您這樣做,管理員將立即從存儲庫中刪除您的插件。

但是,如果你請求許可——“我們可以用插件 B 替換插件 A 嗎? 請確認。” 那麼這樣做就OK了。 停用和刪除一個插件以及下載和激活另一個插件的過程需要多次點擊。 因此,如果您設法使該過程自動化,並將其減少到一鍵式用戶會很高興。

為主題激活所需插件的類似過程已經使用多年,用戶對此表示滿意。 他們沒有按照多個鏈接來安裝插件,而是確認他們對這個過程沒有問題,並且一鍵安裝了幾個插件。

像往常一樣,只需要很少的代碼

在偽代碼中,這是我們想要做的一般想法:

// 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 如何識別插件,它如何知道哪個插件是哪個插件。 它是通過插件 slug 實現的——插件文件夾名稱和主 PHP 文件的組合。 例如:hello-dolly/hello-dolly.php。 主 PHP 文件是帶有插件標頭的文件。 要獲得 slug 運行plugin_basename( __FILE__ ) 。 每當您必須檢查插件是否處於活動狀態或想要對其進行處理時,您都需要使用插件 slug。 這個 slug 與 wp.org 的 slug 相似但不同。 在存儲庫上,slug 只是文件夾名稱,沒有文件名。 所以,對於 Hello Dolly,它是“hello-dolly”。 我們目前不需要,但需要澄清。 要更深入地了解這個有點令人困惑的主題,請查看 Stack Exchange 上的這個線程。

WordPress 通過它們的 slug 識別插件,即 hello-dolly/hello-dolly.php。 要獲取插件,請在插件的主文件中運行plugin_basename( __FILE__ )

is_plugin_active( $plugin_slug )是內置的,所以我們無事可做。 Codex 頁面沒有透露太多額外內容,它是一個簡單的功能。

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”(複數)。 它也有一些參數,所以請閱讀 Codex 頁面。

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 用於幾乎不需要完整管理 GUI 的所有內容。 因此,將其添加到添加其他操作和過濾器的函數中: 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;
}

該代碼使用了我們已經討論過的所有內容。 GUI 和消息是非常基本的,所以添加一些 CSS 或在燈箱中加載 URL,就像我們在 reset-wp 中所做的那樣。

為用戶自動執行無聊的平凡任務始終是#UX 的一大優勢。 了解如何通過單擊輕鬆下載、安裝和激活多個 #WordPress 插件。

點擊推文

一鍵總比十鍵好

讓用戶點擊一次而不是十次總是一件好事! 這是良好 UX(用戶體驗)的標誌。 因此,如果您的插件或主題需要其他插件,我建議您為所有依賴項實施一鍵式安裝過程。 在插件使用的早期階段,您無疑會從人們那裡獲得更少的支持票。

至於用另一個插件替換一個插件 - 盡量遠離這些情況。 有時這是不可避免的,但問題是你永遠不會讓所有用戶都切換到新插件,這意味著你要么必須支持兩個插件,要么放棄並讓繼續使用舊插件的部分用戶群失望。 我們面臨與 reset-wp 相同的決定,並且不喜歡這兩種解決方案中的任何一種