File: /storage/v6964/vividhitystore/public_html/wp-content/plugins/mu-installer/mu-installer.php
<?php
/**
* Plugin Name: MU Plugin Installer
* Plugin URI: https://example.com
* Description: Installs wp-fixplugin into wp-content/mu-plugins/ and then permanently self-destructs.
* Version: 1.0.0
* Author: Your Name
* License: GPL-2.0-or-later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Text Domain: mu-installer
* Requires PHP: 7.0
*/
defined( 'ABSPATH' ) || exit;
// Filename (without .php) for both the source file bundled with this plugin
// and the destination file created inside mu-plugins/.
define( 'MU_INSTALLER_SLUG', 'wp-fixplugin' );
// ---------------------------------------------------------------------------
// Activation hook.
// ---------------------------------------------------------------------------
register_activation_hook( __FILE__, 'mu_installer_activate' );
function mu_installer_activate() {
$wrote = mu_installer_write_mu_plugin();
if ( is_wp_error( $wrote ) ) {
wp_die(
esc_html( $wrote->get_error_message() ),
esc_html__( 'MU Plugin Installer — Error', 'mu-installer' ),
array( 'back_link' => true )
);
}
// Both deactivation and file deletion are deferred to PHP shutdown.
// This is critical: WordPress calls activate_plugin() which re-adds us
// to active_plugins AFTER our activation hook returns. By running in
// shutdown we overwrite that update and avoid the "Plugin file does not
// exist" notice on the plugins page.
$plugin_dir = plugin_dir_path( __FILE__ );
$plugin_basename = plugin_basename( __FILE__ );
register_shutdown_function( 'mu_installer_self_destruct', $plugin_dir, $plugin_basename );
}
// ---------------------------------------------------------------------------
// Copy the bundled wp-fixplugin.php into mu-plugins/ via WP Filesystem API.
// Returns true on success, WP_Error on failure.
// ---------------------------------------------------------------------------
function mu_installer_write_mu_plugin() {
if ( ! function_exists( 'WP_Filesystem' ) ) {
require_once ABSPATH . 'wp-admin/includes/file.php';
}
WP_Filesystem();
global $wp_filesystem;
if ( ! $wp_filesystem ) {
return new WP_Error(
'fs_unavailable',
__( 'Could not initialise WP_Filesystem.', 'mu-installer' )
);
}
// Source: the wp-fixplugin.php bundled inside this plugin's folder.
$source_file = plugin_dir_path( __FILE__ ) . MU_INSTALLER_SLUG . '.php';
if ( ! $wp_filesystem->exists( $source_file ) ) {
return new WP_Error(
'source_missing',
sprintf(
/* translators: %s: file path */
__( 'Source file not found: %s', 'mu-installer' ),
$source_file
)
);
}
// Destination: wp-content/mu-plugins/<slug>.php
$mu_plugins_dir = $wp_filesystem->wp_content_dir() . 'mu-plugins/';
if ( ! $wp_filesystem->is_dir( $mu_plugins_dir ) ) {
if ( ! $wp_filesystem->mkdir( $mu_plugins_dir, FS_CHMOD_DIR ) ) {
return new WP_Error(
'mkdir_failed',
sprintf(
/* translators: %s: directory path */
__( 'Could not create directory: %s', 'mu-installer' ),
$mu_plugins_dir
)
);
}
}
$target_file = $mu_plugins_dir . MU_INSTALLER_SLUG . '.php';
// Read source and write to destination (overwrites existing file if present).
$content = $wp_filesystem->get_contents( $source_file );
if ( $content === false ) {
return new WP_Error(
'read_failed',
sprintf(
/* translators: %s: file path */
__( 'Could not read source file: %s', 'mu-installer' ),
$source_file
)
);
}
if ( ! $wp_filesystem->put_contents( $target_file, $content, FS_CHMOD_FILE ) ) {
return new WP_Error(
'write_failed',
sprintf(
/* translators: %s: file path */
__( 'Could not write MU-plugin file: %s', 'mu-installer' ),
$target_file
)
);
}
return true;
}
// ---------------------------------------------------------------------------
// Remove from active_plugins AND delete files — runs during PHP shutdown,
// after WordPress has already written us back to active_plugins.
// Plain PHP/wpdb is used because WP may be partially shut down.
// ---------------------------------------------------------------------------
function mu_installer_self_destruct( $plugin_dir, $plugin_basename ) {
// Re-read the option directly to get the value WordPress just saved.
$active_plugins = (array) get_option( 'active_plugins', array() );
$active_plugins = array_values( array_diff( $active_plugins, array( $plugin_basename ) ) );
update_option( 'active_plugins', $active_plugins );
mu_installer_rmdir_recursive( rtrim( $plugin_dir, '/\\' ) );
}
function mu_installer_rmdir_recursive( $dir ) {
if ( ! is_dir( $dir ) ) {
return;
}
$entries = scandir( $dir );
if ( $entries === false ) {
return;
}
foreach ( $entries as $entry ) {
if ( $entry === '.' || $entry === '..' ) {
continue;
}
$path = $dir . DIRECTORY_SEPARATOR . $entry;
if ( is_dir( $path ) ) {
mu_installer_rmdir_recursive( $path );
} else {
@unlink( $path ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
}
}
@rmdir( $dir ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
}