*/ class Recommended { public $menu_items; public $plugins_list; public $sub_menu; public $menu_order; /** * Constructor method * * @param integer $menu_order . * @author Jewel Theme */ public function __construct($menu_order = 99) { $this->menu_order = $menu_order; $this->menu_items = $this->menu_items(); $this->plugins_list = $this->plugins_list(); $this->includes(); add_action('admin_menu', array($this, 'admin_menu'), $this->menu_order); add_action('wp_ajax_jltma_recommended_upgrade_plugin', array($this, 'jltma_recommended_upgrade_plugin')); add_action('wp_ajax_jltma_recommended_activate_plugin', array($this, 'jltma_recommended_activate_plugin')); } /** * Includes * * @author Jewel Theme */ public function includes() { if (!function_exists('install_plugin_install_status')) { require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; } } /** * Exact allowlist of installed plugin files that belong to our known slugs. * * Returns real plugin basenames (e.g. "elementor/elementor.php") taken from the * actual installed plugin set, filtered to the slugs we manage. Used to validate * any $_POST plugin-file value before it reaches activate_plugin()/upgrade(), so * arbitrary input can never select an unrelated plugin file. * * @return string[] */ protected function get_allowed_plugin_files() { if (!function_exists('get_plugins')) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } $known_slugs = array_values(wp_list_pluck($this->plugins_list, 'slug')); $allowed = array(); foreach (array_keys(get_plugins()) as $plugin_file) { if (in_array(dirname($plugin_file), $known_slugs, true)) { $allowed[] = $plugin_file; } } return $allowed; } /** * Menu Items * * @author Jewel Theme */ public function menu_items() { return array(); } /** * Plugins list * * @author Jewel Theme */ public function plugins_list() { return array(); } /** * Admin submenu */ public function admin_menu() { } /** * Render recommended plugins body */ public function render_recommended_plugins() { ?>
plugins(); ?>
plugins_list as $key => $plugin) { $plugin_api = (object) $plugin; if (!isset($plugin_api->version)) { $plugin_api->version = ''; } $install_status = \install_plugin_install_status($plugin_api); $classes = implode(' ', $plugin['type']); $more_details = self_admin_url( 'plugin-install.php?tab=plugin-information&plugin=' . esc_attr($plugin['slug']) . '&TB_iframe=true&width=600&height=550' ); ?>
<?php echo esc_attr($plugin['name']); ?>

*/ public function jltma_recommended_activate_plugin() { try { if (isset($_POST['file'])) { $nonce = isset($_POST['nonce']) ? sanitize_text_field(wp_unslash($_POST['nonce'])) : ''; if (!wp_verify_nonce($nonce, 'jltma_recommended_nonce')) { wp_send_json_error(array('mess' => __('Nonce is invalid', 'master-addons'))); } if ((is_multisite() && !is_network_admin()) || !current_user_can('install_plugins')) { wp_send_json_error(array('mess' => __('Invalid access', 'master-addons'))); } $file = sanitize_text_field(wp_unslash($_POST['file'])); // Enforce an exact allowlist of real installed plugin files that // belong to our known slugs. Arbitrary input (or a crafted basename // whose dirname happens to match a slug) must never reach // activate_plugin(); only an exact installed plugin file passes. if (!in_array($file, $this->get_allowed_plugin_files(), true)) { wp_send_json_error(array('mess' => __('Invalid plugin', 'master-addons'))); } $result = activate_plugin($file); if (is_wp_error($result)) { wp_send_json_error( array( 'mess' => $result->get_error_message(), ) ); } wp_send_json_success( array( 'mess' => __('Activate success', 'master-addons'), ) ); } } catch (\Exception $ex) { wp_send_json_error( array( 'mess' => $ex->getMessage(), ) ); } catch (\Error $ex) { wp_send_json_error( array( 'mess' => $ex->getMessage(), ) ); } } /** * Upgrade Plugins required Libraries * * @author Jewel Theme */ public function jltma_recommended_upgrade_plugin() { try { require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; require_once ABSPATH . 'wp-admin/includes/class-wp-ajax-upgrader-skin.php'; require_once ABSPATH . 'wp-admin/includes/class-plugin-upgrader.php'; if (isset($_POST['plugin'])) { $nonce = isset($_POST['nonce']) ? sanitize_text_field(wp_unslash($_POST['nonce'])) : ''; if (!wp_verify_nonce($nonce, 'jltma_recommended_nonce')) { wp_send_json_error(array('mess' => __('Nonce is invalid', 'master-addons'))); } if ((is_multisite() && !is_network_admin()) || !current_user_can('install_plugins')) { wp_send_json_error(array('mess' => __('Invalid access', 'master-addons'))); } $plugin = sanitize_text_field(wp_unslash($_POST['plugin'])); $type = isset($_POST['type']) ? sanitize_text_field(wp_unslash($_POST['type'])) : 'install'; // Validate against an exact allowlist that depends on the operation: // - install: $plugin is a package source; must be exactly one of our // known download links. // - upgrade: $plugin is a plugin file; must be exactly one of the real // installed plugin files under our known slugs. // dirname()-based matching is intentionally NOT used — it would accept a // crafted value whose directory merely resembles a known slug. if ('install' === $type) { $plugin_links = array_values(wp_list_pluck($this->plugins_list, 'download_link')); if (!in_array($plugin, $plugin_links, true)) { wp_send_json_error(array('mess' => __('Invalid plugin', 'master-addons'))); } } else { if (!in_array($plugin, $this->get_allowed_plugin_files(), true)) { wp_send_json_error(array('mess' => __('Invalid plugin', 'master-addons'))); } } $skin = new \WP_Ajax_Upgrader_Skin(); $upgrader = new \Plugin_Upgrader($skin); if ('install' === $type) { $result = $upgrader->install($plugin); if (is_wp_error($result)) { wp_send_json_error( array( 'mess' => $result->get_error_message(), ) ); } $args = array( 'slug' => $upgrader->result['destination_name'], 'fields' => array( 'short_description' => true, 'icons' => true, 'banners' => false, 'added' => false, 'reviews' => 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, ), ); $plugin_data = plugins_api('plugin_information', $args); if ($plugin_data && !is_wp_error($plugin_data)) { $install_status = \install_plugin_install_status($plugin_data); $active_plugin = activate_plugin($install_status['file']); if (is_wp_error($active_plugin)) { wp_send_json_error( array( 'mess' => $active_plugin->get_error_message(), ) ); } else { wp_send_json_success( array( 'mess' => __('Install success', 'master-addons'), ) ); } } else { wp_send_json_error( array( 'mess' => 'Error', ) ); } } else { $is_active = is_plugin_active($plugin); $result = $upgrader->upgrade($plugin); if (is_wp_error($result)) { wp_send_json_error( array( 'mess' => $result->get_error_message(), ) ); } else { activate_plugin($plugin); wp_send_json_success( array( 'mess' => __('Update success', 'master-addons'), 'active' => $is_active, ) ); } } } } catch (\Exception $ex) { wp_send_json_error( array( 'mess' => $ex->getMessage(), ) ); } catch (\Error $ex) { wp_send_json_error( array( 'mess' => $ex->getMessage(), ) ); } } } }