Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
demountable
/
wp-content
/
plugins
/
astra-sites
/
inc
/
lib
/
onboarding
/
classes
:
class-astra-sites-install-plugin.php
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
<?php /** * Astra Sites Install Plugin Class * * This file contains the logic for handling plugin installations during site import via REST API. * * @since 4.4.31 * @package Astra Sites */ if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } if ( ! class_exists( 'Astra_Sites_Install_Plugin' ) ) : /** * Class Astra_Sites_Install_Plugin * * Main class for handling plugin installations during site import via AJAX. */ class Astra_Sites_Install_Plugin { /** * Instance * * @access private * @var object Class object. * @since 4.4.31 */ private static $instance; /** * AJAX action name * * @var string */ private $ajax_action = 'astra_sites_install_plugin'; /** * Initiator * * @since 4.4.31 * @return object initialized object of class. */ public static function get_instance() { if (self::$instance === null) { self::$instance = new self(); } return self::$instance; } /** * Constructor */ public function __construct() { // Register AJAX handler only for logged-in users (plugin installation requires authentication). add_action( 'wp_ajax_' . $this->ajax_action, array( $this, 'handle_ajax_install_plugin' ) ); } /** * Handle AJAX request for plugin installation * * @return void */ public function handle_ajax_install_plugin() { // Set proper content type for JSON response. header( 'Content-Type: application/json' ); try { // Verify nonce for security. if ( ! $this->verify_ajax_nonce() ) { wp_send_json_error( array( 'message' => __( 'Security verification failed. Please refresh the page and try again.', 'astra-sites' ), 'code' => 'nonce_verification_failed', ), 403 ); } // Check user permissions. $permission_check = $this->check_install_plugin_permissions(); if ( is_wp_error( $permission_check ) ) { wp_send_json_error( array( 'message' => $permission_check->get_error_message(), 'code' => $permission_check->get_error_code(), ), 403 ); } // Get and validate plugin data. $plugin_data = $this->get_and_validate_plugin_data(); if ( is_wp_error( $plugin_data ) ) { wp_send_json_error( array( 'message' => $plugin_data->get_error_message(), 'code' => $plugin_data->get_error_code(), ), 400 ); } // Extract plugin information. $plugin_slug = $plugin_data['slug']; $plugin_name = $plugin_data['name']; // Include necessary WordPress files. $this->include_required_files(); // Check if plugin is already installed. $installed_plugins = get_plugins(); $plugin_file = $this->get_plugin_file( $plugin_slug ); if ( $plugin_file && isset( $installed_plugins[ $plugin_file ] ) ) { // Plugin already installed. wp_send_json_success( array( 'message' => sprintf( __( '%s plugin is already installed.', 'astra-sites' ), $plugin_name ), 'status' => 'already_installed', 'data' => array( 'plugin' => array( 'slug' => $plugin_slug, 'name' => $plugin_name, 'file' => $plugin_file, ), ), ) ); } // Install plugin. $install_result = $this->perform_plugin_installation( $plugin_slug, $plugin_name ); if ( is_wp_error( $install_result ) ) { wp_send_json_error( array( 'message' => $install_result->get_error_message(), 'code' => $install_result->get_error_code(), 'data' => $install_result->get_error_data(), ), 500 ); } // Get plugin file after installation. $plugin_file = $this->get_plugin_file( $plugin_slug ); if ( ! $plugin_file ) { wp_send_json_error( array( 'message' => sprintf( __( 'Plugin %s was installed but could not locate plugin file.', 'astra-sites' ), $plugin_name ), 'code' => 'plugin_file_not_found_after_install', ), 500 ); } // Success response. wp_send_json_success( array( 'message' => sprintf( __( '%s plugin installed successfully.', 'astra-sites' ), $plugin_name ), 'status' => 'installed', 'data' => array( 'plugin' => array( 'slug' => $plugin_slug, 'name' => $plugin_name, 'file' => $plugin_file, ), ), ) ); } catch ( Exception $e ) { // Handle any unexpected exceptions. astra_sites_error_log( 'Astra Sites Plugin Installation Error: ' . $e->getMessage() ); wp_send_json_error( array( 'message' => __( 'An unexpected error occurred during plugin installation.', 'astra-sites' ), 'code' => 'unexpected_error', ), 500 ); } } /** * Verify AJAX nonce for security * * @return bool True if nonce is valid, false otherwise. */ private function verify_ajax_nonce() { $nonce = isset( $_POST['_ajax_nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['_ajax_nonce'] ) ) : ''; if ( empty( $nonce ) ) { return false; } // Try multiple nonce actions that might be used in Astra Sites. $nonce_actions = array( 'astra-sites', // Primary nonce action used in other Astra Sites AJAX calls. 'astra_sites_ajax', // Alternative nonce action. 'wp_rest', // WordPress REST API nonce. ); foreach ( $nonce_actions as $action ) { if ( wp_verify_nonce( $nonce, $action ) ) { return true; } } return false; } /** * Check permissions for plugin installation * * @return bool|WP_Error True if user has permission, otherwise WP_Error */ private function check_install_plugin_permissions() { // Check if user has permission to install plugins if ( ! current_user_can( 'install_plugins' ) ) { return new WP_Error( 'insufficient_permissions', __( 'You do not have permissions to install plugins.', 'astra-sites' ) ); } // Additional security check - ensure user is logged in if ( ! is_user_logged_in() ) { return new WP_Error( 'user_not_logged_in', __( 'You must be logged in to install plugins.', 'astra-sites' ) ); } return true; } /** * Get and validate plugin data from AJAX request * * @return array<string, mixed>|WP_Error Plugin data array or WP_Error on failure */ private function get_and_validate_plugin_data() { // Get plugin slug $plugin_slug = isset( $_POST['slug'] ) ? sanitize_text_field( wp_unslash( $_POST['slug'] ) ) : ''; if ( empty( $plugin_slug ) ) { return new WP_Error( 'missing_plugin_slug', __( 'Plugin slug is required.', 'astra-sites' ) ); } // Validate plugin slug format if ( ! $this->validate_plugin_slug( $plugin_slug ) ) { return new WP_Error( 'invalid_plugin_slug', __( 'Plugin slug contains invalid characters.', 'astra-sites' ) ); } // Get plugin name (optional, defaults to slug) $plugin_name = isset( $_POST['name'] ) ? sanitize_text_field( wp_unslash( $_POST['name'] ) ) : $plugin_slug; // Get plugin init (optional) $plugin_init = isset( $_POST['init'] ) ? sanitize_text_field( wp_unslash( $_POST['init'] ) ) : ''; return array( 'slug' => $plugin_slug, 'name' => $plugin_name, 'init' => $plugin_init, ); } /** * Validate plugin slug format * * @param string $slug Plugin slug to validate * @return mixed 1 if valid, false if failure */ private function validate_plugin_slug( $slug ) { // Basic slug validation (alphanumeric, hyphens, underscores) return preg_match( '/^[a-zA-Z0-9_-]+$/', $slug ); } /** * Include required WordPress files * * @return void */ private function include_required_files() { if ( ! function_exists( 'get_plugins' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } if ( ! function_exists( 'request_filesystem_credentials' ) ) { require_once ABSPATH . 'wp-admin/includes/file.php'; } if ( ! class_exists( 'Plugin_Upgrader' ) ) { require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; } } /** * Get plugin file path from slug * * @param string $plugin_slug Plugin slug. * @return string|false Plugin file path or false if not found. */ private function get_plugin_file( $plugin_slug ) { // Try common plugin file patterns $possible_files = array( $plugin_slug . '/' . $plugin_slug . '.php', $plugin_slug . '/index.php', $plugin_slug . '/plugin.php', ); $installed_plugins = get_plugins(); foreach ( $possible_files as $file ) { if ( isset( $installed_plugins[ $file ] ) ) { return $file; } } // Search through all installed plugins for this slug foreach ( $installed_plugins as $file => $plugin_data ) { if ( strpos( $file, $plugin_slug . '/' ) === 0 ) { return $file; } } return false; } /** * Perform plugin installation using WordPress.org repository * * @param string $plugin_slug Plugin slug. * @param string $plugin_name Plugin name. * @return true|WP_Error True on success, WP_Error on failure. */ private function perform_plugin_installation( $plugin_slug, $plugin_name ) { try { // Validate input parameters if ( empty( $plugin_slug ) || empty( $plugin_name ) ) { throw new Exception( __( 'Plugin slug and name are required for installation.', 'astra-sites' ), 0 // code must be int ); } astra_sites_error_log( sprintf( 'Starting installation of plugin %s (%s)', $plugin_name, $plugin_slug ) ); // Step 1: Get plugin API information $api = $this->get_plugin_api_info( $plugin_slug, $plugin_name ); if ( is_wp_error( $api ) ) { return $api; } // Step 2: Perform the actual installation $result = $this->execute_plugin_installation( $api, $plugin_slug, $plugin_name ); if ( is_wp_error( $result ) ) { return $result; } astra_sites_error_log( sprintf( 'Successfully installed plugin %s (%s)', $plugin_name, $plugin_slug ) ); return true; } catch ( Exception $e ) { // Catch any unexpected exceptions $error_message = sprintf( __( 'Unexpected error during %s plugin installation: %s', 'astra-sites' ), $plugin_name, $e->getMessage() ); astra_sites_error_log( sprintf( 'Unexpected exception for plugin %s: %s', $plugin_slug, $e->getMessage() ) ); return new WP_Error( 'unexpected_error', $error_message, array( 'plugin_slug' => $plugin_slug, 'exception_message' => $e->getMessage(), 'exception_code' => $e->getCode(), 'troubleshooting_tips' => array( __( 'Please try the installation again.', 'astra-sites' ), __( 'If the problem persists, try installing the plugin manually from the WordPress admin.', 'astra-sites' ), __( 'Contact your hosting provider if you continue to experience issues.', 'astra-sites' ), ), ) ); } } /** * Get plugin information from WordPress.org API * * @param string $plugin_slug Plugin slug. * @param string $plugin_name Plugin name. * @return object|WP_Error Plugin API object on success, WP_Error on failure. */ private function get_plugin_api_info( $plugin_slug, $plugin_name ) { // Include required WordPress files with error handling try { if ( ! function_exists( 'plugins_api' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; } if ( ! class_exists( 'WP_Ajax_Upgrader_Skin' ) ) { require_once ABSPATH . 'wp-admin/includes/class-wp-ajax-upgrader-skin.php'; } } catch ( Exception $e ) { astra_sites_error_log( sprintf( 'Failed to load required WordPress files for %s: %s', $plugin_slug, $e->getMessage() ) ); return new WP_Error( 'files_load_failed', sprintf( __( 'Failed to load required WordPress files: %s', 'astra-sites' ), $e->getMessage() ), array( 'plugin_slug' => $plugin_slug ) ); } // Get plugin information from WordPress.org API with timeout and retry logic $api_attempts = 0; $max_api_attempts = 2; $api = null; while ( $api_attempts <= $max_api_attempts && ( is_null( $api ) || is_wp_error( $api ) ) ) { $api_attempts++; try { astra_sites_error_log( sprintf( 'API attempt %d for plugin %s', $api_attempts, $plugin_slug ) ); $api = plugins_api( 'plugin_information', array( 'slug' => $plugin_slug, 'fields' => array( 'short_description' => false, 'sections' => false, 'requires' => false, 'rating' => false, 'ratings' => false, 'downloaded' => false, 'last_updated' => false, 'added' => false, 'tags' => false, 'compatibility' => false, 'homepage' => false, 'donate_link' => false, ), ) ); // Break if successful if ( ! is_wp_error( $api ) && ! empty( $api->download_link ) ) { break; } // Wait before retry (except on last attempt) if ( $api_attempts < $max_api_attempts ) { sleep( 1 ); } } catch ( Exception $e ) { astra_sites_error_log( sprintf( 'API exception on attempt %d for %s: %s', $api_attempts, $plugin_slug, $e->getMessage() ) ); if ( $api_attempts >= $max_api_attempts ) { return new WP_Error( 'api_exception', sprintf( __( 'Plugin API request failed after %d attempts: %s', 'astra-sites' ), $max_api_attempts, $e->getMessage() ), array( 'plugin_slug' => $plugin_slug ) ); } } } if ( ! $api ) { astra_sites_error_log( sprintf( 'API failed to return data for plugin %s', $plugin_slug ) ); return new WP_Error( 'plugin_api_failed', sprintf( __( 'Could not retrieve plugin information for %s', 'astra-sites' ), $plugin_name ) ); } // Handle API errors if ( is_wp_error( $api ) && $api instanceof WP_Error ) { $api_error_message = $api->get_error_message(); $api_error_code = $api->get_error_code(); astra_sites_error_log( sprintf( 'API error for plugin %s: %s (%s)', $plugin_slug, $api_error_message, $api_error_code ) ); // Provide specific error messages based on API error codes switch ( $api_error_code ) { case 'plugins_api_failed': $user_message = sprintf( __( 'Could not connect to WordPress.org plugin repository for %s. Please check your internet connection and try again.', 'astra-sites' ), $plugin_name ); break; case 'plugin_not_found': $user_message = sprintf( __( 'Plugin %s was not found in the WordPress.org repository. Please verify the plugin name and try again.', 'astra-sites' ), $plugin_name ); break; default: $user_message = sprintf( __( 'Could not retrieve plugin information for %s from WordPress.org. Error: %s', 'astra-sites' ), $plugin_name, $api_error_message ); break; } return new WP_Error( 'plugin_api_failed', $user_message, array( 'plugin_slug' => $plugin_slug, 'api_error' => $api_error_message, 'api_error_code' => $api_error_code, 'attempts_made' => $api_attempts, ) ); } // Validate API response if ( ! is_object( $api ) ) { astra_sites_error_log( sprintf( 'Invalid API response for plugin %s', $plugin_slug ) ); return new WP_Error( 'invalid_api_response', sprintf( __( 'Received invalid response from WordPress.org for plugin %s.', 'astra-sites' ), $plugin_name ), array( 'plugin_slug' => $plugin_slug ) ); } // Check for download URL if ( empty( $api->download_link ) ) { astra_sites_error_log( sprintf( 'No download URL found for plugin %s', $plugin_slug ) ); return new WP_Error( 'no_download_url', sprintf( __( 'Could not find download URL for %s. The plugin may not be available in WordPress.org repository or may be a premium plugin.', 'astra-sites' ), $plugin_name ), array( 'plugin_slug' => $plugin_slug, 'api_response' => $api, ) ); } return $api; } /** * Execute the actual plugin installation * * @param object $api Plugin API object. * @param string $plugin_slug Plugin slug. * @param string $plugin_name Plugin name. * @return true|WP_Error True on success, WP_Error on failure. */ private function execute_plugin_installation( $api, $plugin_slug, $plugin_name ) { // Validate WordPress and PHP requirements try { $this->validate_plugin_requirements( $api, $plugin_name ); } catch ( Exception $e ) { astra_sites_error_log( sprintf( 'Requirements not met for plugin %s: %s', $plugin_slug, $e->getMessage() ) ); return new WP_Error( 'requirements_not_met', $e->getMessage(), array( 'plugin_slug' => $plugin_slug, 'requirements' => array( 'requires' => isset( $api->requires ) ? $api->requires : '', 'requires_php' => isset( $api->requires_php ) ? $api->requires_php : '', ), ) ); } // Check available disk space try { $this->check_disk_space( $plugin_name ); } catch ( Exception $e ) { astra_sites_error_log( sprintf( 'Insufficient disk space for plugin %s: %s', $plugin_slug, $e->getMessage() ) ); return new WP_Error( 'insufficient_disk_space', $e->getMessage(), array( 'plugin_slug' => $plugin_slug ) ); } // Set up the Plugin_Upgrader with enhanced error handling try { $upgrader_skin = new WP_Ajax_Upgrader_Skin(); $upgrader = new Plugin_Upgrader( $upgrader_skin ); } catch ( Exception $e ) { astra_sites_error_log( sprintf( 'Failed to initialize upgrader for plugin %s: %s', $plugin_slug, $e->getMessage() ) ); return new WP_Error( 'upgrader_init_failed', sprintf( __( 'Failed to initialize plugin installer for %s: %s', 'astra-sites' ), $plugin_name, $e->getMessage() ), array( 'plugin_slug' => $plugin_slug ) ); } // Perform the actual installation with detailed error handling // @phpstan-ignore-next-line astra_sites_error_log( sprintf( 'Starting plugin installation for %s from %s', $plugin_slug, $api->download_link ) ); $result = null; try { // @phpstan-ignore-next-line $result = $upgrader->install( $api->download_link ); } catch ( Exception $e ) { astra_sites_error_log( sprintf( 'Installation exception for plugin %s: %s', $plugin_slug, $e->getMessage() ) ); return new WP_Error( 'installation_exception', sprintf( __( 'Plugin %s installation failed with exception: %s', 'astra-sites' ), $plugin_name, $e->getMessage() ), array( 'plugin_slug' => $plugin_slug, 'exception_message' => $e->getMessage(), ) ); } // Handle installation result errors if ( is_wp_error( $result ) ) { $error_message = $result->get_error_message(); $error_code = $result->get_error_code(); $error_data = $result->get_error_data(); astra_sites_error_log( sprintf( 'Installation error for plugin %s: %s (%s)', $plugin_slug, $error_message, $error_code ) ); // Enhanced error messages based on common installation issues $enhanced_message = $this->get_enhanced_error_message( $error_code, $error_message, $plugin_name ); return new WP_Error( 'installation_failed', $enhanced_message, array( 'plugin_slug' => $plugin_slug, 'original_error' => $error_message, 'error_code' => $error_code, 'error_data' => $error_data, 'troubleshooting_tips' => $this->get_troubleshooting_tips( $error_code ), ) ); } // Check if installation was unsuccessful if ( ! $result ) { astra_sites_error_log( sprintf( 'Installation returned false for plugin %s', $plugin_slug ) ); return new WP_Error( 'installation_failed', sprintf( __( 'Plugin %s installation failed: Unknown error occurred during installation. Please try again or install the plugin manually.', 'astra-sites' ), $plugin_name ), array( 'plugin_slug' => $plugin_slug, 'troubleshooting_tips' => array( __( 'Try refreshing the page and attempting the installation again.', 'astra-sites' ), __( 'Check if you have sufficient permissions to install plugins.', 'astra-sites' ), __( 'Verify that your WordPress installation has write permissions to the plugins directory.', 'astra-sites' ), ), ) ); } // Verify installation by checking if plugin files exist try { $this->verify_plugin_installation( $plugin_slug, $plugin_name ); } catch ( Exception $e ) { astra_sites_error_log( sprintf( 'Installation verification failed for plugin %s: %s', $plugin_slug, $e->getMessage() ) ); return new WP_Error( 'installation_verification_failed', $e->getMessage(), array( 'plugin_slug' => $plugin_slug ) ); } return true; } /** * Validate plugin requirements against current WordPress and PHP versions * * @param object $api Plugin API response object. * @param string $plugin_name Plugin name. * @throws Exception If requirements are not met. * @return void */ private function validate_plugin_requirements( $api, $plugin_name ) { global $wp_version; // Check WordPress version requirement if ( ! empty( $api->requires ) ) { if ( version_compare( $wp_version, $api->requires, '<' ) ) { throw new Exception( sprintf( __( 'Plugin %s requires WordPress version %s or higher. You are currently running version %s. Please update WordPress first.', 'astra-sites' ), $plugin_name, $api->requires, $wp_version ) ); } } // Check PHP version requirement if ( ! empty( $api->requires_php ) ) { if ( version_compare( PHP_VERSION, $api->requires_php, '<' ) ) { throw new Exception( sprintf( __( 'Plugin %s requires PHP version %s or higher. You are currently running version %s. Please contact your hosting provider to upgrade PHP.', 'astra-sites' ), $plugin_name, $api->requires_php, PHP_VERSION ) ); } } } /** * Check available disk space before installation * * @param string $plugin_name Plugin name. * @throws Exception If insufficient disk space. * @return void */ private function check_disk_space( $plugin_name ) { $wp_content_dir = WP_CONTENT_DIR; // Check if we can get disk space information if ( function_exists( 'disk_free_space' ) && is_dir( $wp_content_dir ) ) { $free_bytes = disk_free_space( $wp_content_dir ); $required_bytes = 50 * 1024 * 1024; // 50MB minimum requirement if ( $free_bytes !== false && $free_bytes < $required_bytes ) { throw new Exception( sprintf( __( 'Insufficient disk space to install %s. At least 50MB of free space is required. Please free up some disk space and try again.', 'astra-sites' ), $plugin_name ) ); } } } /** * Verify plugin installation by checking if plugin files exist * * @param string $plugin_slug Plugin slug. * @param string $plugin_name Plugin name. * @throws Exception If plugin verification fails. * @return void */ private function verify_plugin_installation( $plugin_slug, $plugin_name ) { // Clear plugin cache to ensure fresh data wp_clean_plugins_cache(); // Check if plugin directory exists $plugin_dir = WP_PLUGIN_DIR . '/' . $plugin_slug; if ( ! is_dir( $plugin_dir ) ) { throw new Exception( sprintf( __( 'Plugin %s installation verification failed: Plugin directory not found after installation. The installation may have been incomplete.', 'astra-sites' ), $plugin_name ) ); } // Try to find the main plugin file $plugin_file = $this->get_plugin_file( $plugin_slug ); if ( ! $plugin_file ) { throw new Exception( sprintf( __( 'Plugin %s installation verification failed: Could not locate main plugin file after installation.', 'astra-sites' ), $plugin_name ) ); } // Check if the plugin file is readable $full_plugin_path = WP_PLUGIN_DIR . '/' . $plugin_file; if ( ! is_readable( $full_plugin_path ) ) { throw new Exception( sprintf( __( 'Plugin %s installation verification failed: Plugin file exists but is not readable. Please check file permissions.', 'astra-sites' ), $plugin_name ) ); } } /** * Get enhanced error message based on error code * * @param string|int $error_code Error code. * @param string $error_message Original error message. * @param string $plugin_name Plugin name. * @return string Enhanced error message. */ private function get_enhanced_error_message( $error_code, $error_message, $plugin_name ) { $error_code = (string) $error_code; switch ( $error_code ) { case 'folder_exists': return sprintf( __( 'Plugin %s installation failed: Plugin folder already exists. This usually means the plugin is already installed. Try refreshing the plugins page to see if it appears.', 'astra-sites' ), $plugin_name ); case 'no_credentials': case 'request_filesystem_credentials': return sprintf( __( 'Plugin %s installation failed: WordPress does not have permission to write files. Please check that your web server has write permissions to the plugins directory (/wp-content/plugins/), or contact your hosting provider for assistance.', 'astra-sites' ), $plugin_name ); case 'fs_unavailable': case 'fs_error': return sprintf( __( 'Plugin %s installation failed: Filesystem is not accessible. This is usually a server configuration issue. Please contact your hosting provider to resolve filesystem access problems.', 'astra-sites' ), $plugin_name ); case 'download_failed': case 'http_request_failed': return sprintf( __( 'Plugin %s installation failed: Could not download plugin file from WordPress.org. Please check your internet connection and try again. If the problem persists, your server may be blocking outbound connections.', 'astra-sites' ), $plugin_name ); case 'incompatible_archive': case 'empty_archive': return sprintf( __( 'Plugin %s installation failed: The downloaded plugin file appears to be corrupted or invalid. Please try the installation again.', 'astra-sites' ), $plugin_name ); case 'mkdir_failed': return sprintf( __( 'Plugin %s installation failed: Could not create plugin directory. Please check that your web server has write permissions to the plugins directory.', 'astra-sites' ), $plugin_name ); case 'copy_failed': return sprintf( __( 'Plugin %s installation failed: Could not copy plugin files. This may be due to insufficient disk space or file permission issues.', 'astra-sites' ), $plugin_name ); default: return sprintf( __( 'Plugin %s installation failed: %s. Please try again or install the plugin manually from the WordPress admin area.', 'astra-sites' ), $plugin_name, $error_message ); } } /** * Get troubleshooting tips based on error code * * @param string|int $error_code Error code. * @return array<int, string> Array of troubleshooting tips. */ private function get_troubleshooting_tips( $error_code ) { $common_tips = array( __( 'Try refreshing the page and attempting the installation again.', 'astra-sites' ), __( 'If the problem persists, try installing the plugin manually from WordPress admin > Plugins > Add New.', 'astra-sites' ), ); switch ( $error_code ) { case 'folder_exists': return array_merge( array( __( 'Check if the plugin is already installed by going to Plugins > Installed Plugins.', 'astra-sites' ), __( 'If the plugin appears but is not working, try deactivating and reactivating it.', 'astra-sites' ), ), $common_tips ); case 'no_credentials': case 'request_filesystem_credentials': case 'fs_unavailable': case 'fs_error': case 'mkdir_failed': case 'copy_failed': return array_merge( array( __( 'Contact your hosting provider to check file permissions for the /wp-content/plugins/ directory.', 'astra-sites' ), __( 'Ensure your web server has write permissions to the WordPress installation directory.', 'astra-sites' ), __( 'Check if there is sufficient disk space available on your server.', 'astra-sites' ), ), $common_tips ); case 'download_failed': case 'http_request_failed': return array_merge( array( __( 'Check your internet connection and try again.', 'astra-sites' ), __( 'Contact your hosting provider if your server is blocking outbound connections to WordPress.org.', 'astra-sites' ), __( 'Try installing the plugin at a different time when server load might be lower.', 'astra-sites' ), ), $common_tips ); case 'incompatible_archive': case 'empty_archive': return array_merge( array( __( 'The plugin download may have been corrupted. Try the installation again.', 'astra-sites' ), __( 'Clear your browser cache and try again.', 'astra-sites' ), ), $common_tips ); default: return array_merge( array( __( 'Check the WordPress error logs for more detailed information about the failure.', 'astra-sites' ), __( 'Contact your hosting provider if you continue to experience issues.', 'astra-sites' ), ), $common_tips ); } } } endif; // Initialize the class Astra_Sites_Install_Plugin::get_instance();