'POST', 'callback' => [__CLASS__, 'check_plugin_status'], 'permission_callback' => function () { return current_user_can('install_plugins'); } ] ]); register_rest_route('plac/v1', '/plugins/install', [ [ 'methods' => 'POST', 'callback' => [__CLASS__, 'install_plugin'], 'permission_callback' => function () { return current_user_can('install_plugins'); } ] ]); } public static function check_plugin_status(WP_REST_Request $request) { $nonce = $request->get_param('_wpnonce'); if (!isset($nonce) || !wp_verify_nonce($nonce, 'pl_access_control_wp_rest')) { return new WP_Error('invalid_nonce', 'Invalid nonce', ['status' => 403]); } $slug = $request->get_param('slug'); if (empty($slug)) { return new WP_Error('missing_slug', 'Plugin slug is required', ['status' => 400]); } if (!function_exists('get_plugins')) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } $all_plugins = get_plugins(); $plugin_file = null; $status = 'not_installed'; foreach ($all_plugins as $file => $plugin) { $folder = explode('/', $file)[0]; if ($folder === $slug) { $plugin_file = $file; $status = is_plugin_active($file) ? 'activated' : 'installed'; break; } } return [ 'status' => $status, 'plugin_file' => $plugin_file ]; } public static function install_plugin(WP_REST_Request $request) { ob_start(); $data = json_decode($request->get_body(), true); if (!isset($data['_wpnonce']) || !wp_verify_nonce($data['_wpnonce'], 'pl_access_control_wp_rest')) { ob_end_clean(); return new WP_REST_Response([ 'success' => false, 'message' => 'Invalid nonce' ], 403); } unset($data['_wpnonce']); $plugin_name = sanitize_text_field($data['plugin_name'] ?? ''); $download_url = esc_url_raw($data['download_url'] ?? ''); if (empty($plugin_name) || empty($download_url)) { ob_end_clean(); return new WP_REST_Response([ 'success' => false, 'message' => 'Plugin name or download URL is missing' ], 400); } if (!function_exists('WP_Filesystem')) { require_once ABSPATH . 'wp-admin/includes/file.php'; } if (!WP_Filesystem()) { ob_end_clean(); return new WP_REST_Response([ 'success' => false, 'message' => 'Cannot initialize filesystem' ], 500); } if (!class_exists('\Plugin_Upgrader')) { require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; } $skin = new \WP_Ajax_Upgrader_Skin(); $upgrader = new \Plugin_Upgrader($skin); $result = $upgrader->install($download_url); if (is_wp_error($result)) { ob_end_clean(); return new WP_REST_Response([ 'success' => false, 'message' => $result->get_error_message() ], 500); } if ($skin->get_errors()->has_errors()) { ob_end_clean(); return new WP_REST_Response([ 'success' => false, 'message' => $skin->get_error_messages() ], 500); } if (!function_exists('get_plugins')) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } $installed_plugins = get_plugins(); $new_plugin = null; foreach ($installed_plugins as $plugin_path => $plugin_data) { if (stripos($plugin_data['Name'], $plugin_name) !== false) { $new_plugin = $plugin_path; break; } } ob_end_clean(); if ($new_plugin) { return new WP_REST_Response([ 'success' => true, 'plugin_file' => $new_plugin, 'message' => 'Plugin installed. Please activate it from the Plugins page.' ], 200); } return new WP_REST_Response([ 'success' => false, 'message' => 'Installed plugin could not be identified' ], 404); } }