Plugin & Theme Installation API
WordPress provides a comprehensive upgrader system for installing, updating, and managing plugins and themes. The core class is WP_Upgrader with specialized subclasses.
Class Hierarchy
WP_Upgrader (base class)
├── Plugin_Upgrader
├── Theme_Upgrader
├── Language_Pack_Upgrader
└── Core_Upgrader
WP_Upgrader Base Class
The base class provides common functionality for all upgrade operations.
Core Methods
class WP_Upgrader {
// Download a package
public function download_package( $package, $check_signatures = false, $hook_extra = array() );
// Unpack a compressed package
public function unpack_package( $package, $delete_package = true );
// Install from unpacked package
public function install_package( $args = array() );
// Run an upgrade/install
public function run( $options );
// Connect to filesystem
public function fs_connect( $directories = array(), $allow_relaxed_file_ownership = false );
}
Plugin Installation
Using Plugin_Upgrader
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
// Create upgrader with skin
$upgrader = new Plugin_Upgrader( new WP_Ajax_Upgrader_Skin() );
// Install from WordPress.org
$result = $upgrader->install( 'https://downloads.wordpress.org/plugin/akismet.zip' );
if ( is_wp_error( $result ) ) {
echo $result->get_error_message();
} elseif ( $result ) {
echo 'Plugin installed successfully';
}
Install from Uploaded File
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
require_once ABSPATH . 'wp-admin/includes/file.php';
// Handle upload
$file_upload = new File_Upload_Upgrader( 'pluginzip', 'package' );
$upgrader = new Plugin_Upgrader( new Plugin_Installer_Skin() );
$result = $upgrader->install( $file_upload->package );
Update a Plugin
$upgrader = new Plugin_Upgrader( new Bulk_Upgrader_Skin() );
// Update specific plugin
$result = $upgrader->upgrade( 'plugin-folder/plugin-file.php' );
// Bulk update
$plugins = array(
'akismet/akismet.php',
'hello-dolly/hello.php',
);
$results = $upgrader->bulk_upgrade( $plugins );
Plugin_Upgrader Methods
class Plugin_Upgrader extends WP_Upgrader {
// Install plugin from URL/path
public function install( $package, $args = array() );
// Update single plugin
public function upgrade( $plugin, $args = array() );
// Update multiple plugins
public function bulk_upgrade( $plugins, $args = array() );
}
Theme Installation
Using Theme_Upgrader
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
$upgrader = new Theme_Upgrader( new Theme_Installer_Skin() );
// Install from WordPress.org
$result = $upgrader->install( 'https://downloads.wordpress.org/theme/flavflavor.zip' );
if ( is_wp_error( $result ) ) {
echo $result->get_error_message();
}
Update a Theme
$upgrader = new Theme_Upgrader( new Theme_Upgrader_Skin() );
// Update specific theme
$result = $upgrader->upgrade( 'theme-slug' );
// Bulk update
$themes = array( 'theme-one', 'theme-two' );
$results = $upgrader->bulk_upgrade( $themes );
Theme_Upgrader Methods
class Theme_Upgrader extends WP_Upgrader {
// Install theme from URL/path
public function install( $package, $args = array() );
// Update single theme
public function upgrade( $theme, $args = array() );
// Update multiple themes
public function bulk_upgrade( $themes, $args = array() );
// Check parent theme requirements
public function check_parent_theme_filter( $install_result, $hook_extra, $child_result );
}
Upgrader Skins
Skins control the output/feedback during installation.
Available Skins
| Skin Class | Use Case |
|---|---|
WP_Upgrader_Skin |
Base skin |
Plugin_Upgrader_Skin |
Single plugin upgrade |
Theme_Upgrader_Skin |
Single theme upgrade |
Bulk_Upgrader_Skin |
Bulk upgrades |
Bulk_Plugin_Upgrader_Skin |
Bulk plugin upgrades |
Bulk_Theme_Upgrader_Skin |
Bulk theme upgrades |
Plugin_Installer_Skin |
Plugin installation |
Theme_Installer_Skin |
Theme installation |
Language_Pack_Upgrader_Skin |
Language packs |
Automatic_Upgrader_Skin |
Background updates |
WP_Ajax_Upgrader_Skin |
AJAX updates |
Using WP_Ajax_Upgrader_Skin
For AJAX/background operations (no output):
$skin = new WP_Ajax_Upgrader_Skin();
$upgrader = new Plugin_Upgrader( $skin );
$result = $upgrader->install( $package_url );
// Get messages
$messages = $skin->get_upgrade_messages();
// Get errors
if ( $skin->get_errors()->has_errors() ) {
$errors = $skin->get_errors();
}
Custom Skin
class My_Custom_Skin extends WP_Upgrader_Skin {
public function header() {
echo '<div class="my-upgrade-wrapper">';
}
public function footer() {
echo '</div>';
}
public function feedback( $string, ...$args ) {
if ( ! empty( $args ) ) {
$string = vsprintf( $string, $args );
}
echo '<p class="my-feedback">' . esc_html( $string ) . '</p>';
}
public function error( $errors ) {
echo '<p class="my-error">' . esc_html( $errors ) . '</p>';
}
}
Silent/Background Installation
function silent_plugin_install( $package_url ) {
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
// Use skin that captures output
$skin = new Automatic_Upgrader_Skin();
$upgrader = new Plugin_Upgrader( $skin );
// Install silently
$result = $upgrader->install( $package_url );
if ( is_wp_error( $result ) ) {
return $result;
}
// Get the installed plugin file
$plugin_info = $upgrader->plugin_info();
// Optionally activate
if ( $plugin_info ) {
activate_plugin( $plugin_info );
}
return $plugin_info;
}
Plugin Management Functions
Get Plugin Data
// Get plugin header information
$plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/plugin-folder/plugin-file.php' );
/*
array(
'Name' => 'Plugin Name',
'PluginURI' => 'https://example.com',
'Version' => '1.0.0',
'Description' => 'Plugin description',
'Author' => 'Author Name',
'AuthorURI' => 'https://author.com',
'TextDomain' => 'plugin-textdomain',
'DomainPath' => '/languages',
'Network' => false,
'RequiresWP' => '5.0',
'RequiresPHP' => '7.4',
)
*/
Get All Plugins
// All plugins
$plugins = get_plugins();
// MU-plugins
$mu_plugins = get_mu_plugins();
// Drop-ins
$dropins = get_dropins();
Activate/Deactivate
// Activate
$result = activate_plugin( 'plugin-folder/plugin-file.php' );
if ( is_wp_error( $result ) ) {
// Activation failed
}
// Deactivate
deactivate_plugins( 'plugin-folder/plugin-file.php' );
// Deactivate multiple
deactivate_plugins( array(
'plugin-one/plugin.php',
'plugin-two/plugin.php',
), true ); // true = silent (no hooks)
Delete Plugin
$result = delete_plugins( array( 'plugin-folder/plugin-file.php' ) );
if ( is_wp_error( $result ) ) {
echo $result->get_error_message();
}
Theme Management Functions
Get Theme Data
$theme = wp_get_theme( 'theme-slug' );
if ( $theme->exists() ) {
$name = $theme->get( 'Name' );
$version = $theme->get( 'Version' );
$author = $theme->get( 'Author' );
}
Get All Themes
$themes = wp_get_themes();
foreach ( $themes as $theme_slug => $theme ) {
echo $theme->get( 'Name' );
}
Switch/Delete Theme
// Switch active theme
switch_theme( 'theme-slug' );
// Delete theme
delete_theme( 'theme-slug' );
Checking for Updates
Force Update Check
// Force check for plugin updates
wp_clean_plugins_cache();
delete_site_transient( 'update_plugins' );
wp_update_plugins();
// Force check for theme updates
delete_site_transient( 'update_themes' );
wp_update_themes();
// Force check for core updates
wp_version_check();
Get Available Updates
// Plugin updates
$updates = get_site_transient( 'update_plugins' );
if ( isset( $updates->response ) ) {
foreach ( $updates->response as $plugin => $data ) {
echo $plugin . ' has update: ' . $data->new_version;
}
}
// Theme updates
$updates = get_site_transient( 'update_themes' );
if ( isset( $updates->response ) ) {
foreach ( $updates->response as $theme => $data ) {
echo $theme . ' has update: ' . $data['new_version'];
}
}
WP_Automatic_Updater
For automatic background updates.
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
$auto_updater = new WP_Automatic_Updater();
// Check if auto-updates are disabled
if ( $auto_updater->is_disabled() ) {
return;
}
// Check if specific update should run
$should_update = $auto_updater->should_update( 'plugin', $update_data, ABSPATH );
// Run auto-updates
$auto_updater->run();
Hooks
Installation Hooks
| Hook | Description |
|---|---|
upgrader_pre_download |
Before downloading package |
upgrader_pre_install |
Before installation |
upgrader_post_install |
After installation |
upgrader_process_complete |
After upgrade process |
upgrader_package_options |
Filter package options |
Plugin-Specific
| Hook | Description |
|---|---|
activate_plugin |
During plugin activation |
deactivate_plugin |
During plugin deactivation |
activated_plugin |
After plugin activated |
deactivated_plugin |
After plugin deactivated |
deleted_plugin |
After plugin deleted |
Theme-Specific
| Hook | Description |
|---|---|
switch_theme |
When theme is switched |
after_switch_theme |
After theme switch |
deleted_theme |
After theme deleted |
Error Handling
$upgrader = new Plugin_Upgrader( new WP_Ajax_Upgrader_Skin() );
$result = $upgrader->install( $package_url );
if ( is_wp_error( $result ) ) {
$error_code = $result->get_error_code();
$error_msg = $result->get_error_message();
switch ( $error_code ) {
case 'no_package':
// Package URL not available
break;
case 'download_failed':
// Could not download
break;
case 'incompatible_archive':
// Invalid package structure
break;
case 'mkdir_failed':
// Could not create directory
break;
case 'folder_exists':
// Plugin/theme already exists
break;
}
}
Complete Example: Plugin Auto-Installer
function auto_install_required_plugins() {
$required = array(
'akismet' => 'https://downloads.wordpress.org/plugin/akismet.zip',
'jetpack' => 'https://downloads.wordpress.org/plugin/jetpack.zip',
);
$installed = get_plugins();
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
foreach ( $required as $slug => $url ) {
// Check if already installed
$plugin_file = null;
foreach ( $installed as $file => $data ) {
if ( strpos( $file, $slug ) === 0 ) {
$plugin_file = $file;
break;
}
}
if ( $plugin_file ) {
// Already installed, just activate
if ( ! is_plugin_active( $plugin_file ) ) {
activate_plugin( $plugin_file );
}
continue;
}
// Install the plugin
$skin = new Automatic_Upgrader_Skin();
$upgrader = new Plugin_Upgrader( $skin );
$result = $upgrader->install( $url );
if ( ! is_wp_error( $result ) && $result ) {
$plugin_file = $upgrader->plugin_info();
if ( $plugin_file ) {
activate_plugin( $plugin_file );
}
}
}
}