# betterdocs/4.9.0/includes/Core/PluginInstaller.php

BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ &amp; Chatbot, version 4.9.0. 272 lines.

- Page: https://pluginprobe.com/plugins/betterdocs/4.9.0/code/includes/Core/PluginInstaller.php
- Raw: https://pluginprobe.com/plugins/betterdocs/4.9.0/raw/includes/Core/PluginInstaller.php
- Modified: 2026-08-20T11:38:12+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/betterdocs/4.9.0/code/includes/Core/PluginInstaller.php#L10-L20`.

```php
<?php
namespace WPDeveloper\BetterDocs\Core;

if (!defined('ABSPATH')) {
    exit;
} // Exit if accessed directly.

use \WP_Error;

class PluginInstaller
{
	public function __construct() {
		add_action( 'wp_ajax_wpdeveloper_auto_active_even_not_installed', [ $this, 'ajax_auto_active_even_not_installed' ] );
		add_action( 'wp_ajax_wpdeveloper_install_plugin', [ $this, 'ajax_install_plugin' ] );
		add_action( 'wp_ajax_wpdeveloper_upgrade_plugin', [ $this, 'ajax_upgrade_plugin' ] );
		add_action( 'wp_ajax_wpdeveloper_activate_plugin', [ $this, 'ajax_activate_plugin' ] );
		add_action( 'wp_ajax_wpdeveloper_deactivate_plugin', [ $this, 'ajax_deactivate_plugin' ] );
	}

    /**
     * get_local_plugin_data
     *
     * @param  mixed $basename
     * @return array|false
     */
    public function get_local_plugin_data($basename = '')
    {
        if (empty($basename)) {
            return false;
        }

        if (!function_exists('get_plugins')) {
            include_once ABSPATH . 'wp-admin/includes/plugin.php';
        }

        $plugins = get_plugins();

        if (!isset($plugins[$basename])) {
            return false;
        }

        return $plugins[$basename];
    }

    /**
     * get_remote_plugin_data
     *
     * @param  mixed $slug
     * @return mixed array|WP_Error
     */
    public function get_remote_plugin_data($slug = '')
    {
        if (empty($slug)) {
            return new WP_Error('empty_arg', __('Argument should not be empty.', 'betterdocs'));
        }

        // Use core's plugins_api() instead of a hand-rolled request. The old code
        // POSTed to plaintext http://api.wordpress.org and passed the response
        // body straight to unserialize(), so anyone able to intercept that
        // connection could inject a PHP-object-injection payload or a malicious
        // download_link. plugins_api() talks to api.wordpress.org over HTTPS and
        // returns a decoded object — no plaintext transport, no unserialize().
        if (!function_exists('plugins_api')) {
            include_once ABSPATH . 'wp-admin/includes/plugin-install.php';
        }

        $response = plugins_api('plugin_information', [
            'slug'   => $slug,
            'fields' => [
                'version' => true,
            ],
        ]);

        if (is_wp_error($response) || !is_object($response)) {
            return is_wp_error($response) ? $response : new WP_Error('plugins_api_failed', __('Could not retrieve plugin information.', 'betterdocs'));
        }

        // Bind the package to the requested slug and to an https WordPress.org
        // host before anything installs it.
        if (isset($response->slug) && $response->slug !== $slug) {
            return new WP_Error('slug_mismatch', __('Plugin information did not match the requested plugin.', 'betterdocs'));
        }

        if (isset($response->download_link) && !$this->is_allowed_package_url($response->download_link)) {
            return new WP_Error('bad_package_host', __('Plugin download URL is not an approved WordPress.org address.', 'betterdocs'));
        }

        return $response;
    }

    /**
     * Whether a package URL is safe to hand to the upgrader: https on a
     * WordPress.org host. Prevents a tampered response from redirecting the
     * install to an attacker-controlled archive.
     *
     * @param string $url
     * @return bool
     */
    protected function is_allowed_package_url($url)
    {
        if (!is_string($url) || $url === '') {
            return false;
        }

        $parts = wp_parse_url($url);

        if (empty($parts['scheme']) || strtolower($parts['scheme']) !== 'https' || empty($parts['host'])) {
            return false;
        }

        $host = strtolower($parts['host']);

        return in_array($host, ['downloads.wordpress.org', 'wordpress.org', 'www.wordpress.org'], true);
    }

    /**
     * install_plugin
     *
     * @param  mixed $slug
     * @param  bool $active
     * @return mixed bool|WP_Error
     */
    public function install_plugin($slug = '', $active = true)
    {
        if (empty($slug)) {
            return new WP_Error('empty_arg', __('Argument should not be empty.', 'betterdocs'));
        }

        include_once ABSPATH . 'wp-admin/includes/file.php';
        include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
        include_once ABSPATH . 'wp-admin/includes/class-automatic-upgrader-skin.php';

        $plugin_data = $this->get_remote_plugin_data($slug);

        if (is_wp_error($plugin_data)) {
            return $plugin_data;
        }

        $upgrader = new \Plugin_Upgrader(new \Automatic_Upgrader_Skin());

        // install plugin
        $install = $upgrader->install($plugin_data->download_link);

        if (is_wp_error($install)) {
            return $install;
        }

        // activate plugin
        if ($install === true && $active) {
            $active = activate_plugin($upgrader->plugin_info(), '', false, true);

            if (is_wp_error($active)) {
                return $active;
            }

            return $active === null;
        }

        return $install;
    }

    /**
     * upgrade_plugin
     *
     * @param  mixed $basename
     * @return mixed bool|WP_Error
     */
    public function upgrade_plugin($basename = '')
    {
        if (empty($basename)) {
            return new WP_Error('empty_arg', __('Argument should not be empty.', 'betterdocs'));
        }

        include_once ABSPATH . 'wp-admin/includes/file.php';
        include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
        include_once ABSPATH . 'wp-admin/includes/class-automatic-upgrader-skin.php';

        $upgrader = new \Plugin_Upgrader(new \Automatic_Upgrader_Skin());

        // upgrade plugin
        return $upgrader->upgrade($basename);
    }

    public function ajax_install_plugin()
    {
        check_ajax_referer('betterdocs-wpdeveloper-plugins', 'security');

        if(!current_user_can( 'install_plugins' )) {
            wp_send_json_error(__('you are not allowed to do this action', 'betterdocs'));
        }

	    $slug   = isset( $_POST['slug'] ) ? sanitize_text_field( wp_unslash( $_POST['slug'] ) ) : '';
	    $result = $this->install_plugin( $slug );

        $promotype = isset( $_POST['promotype'] ) ? sanitize_text_field( wp_unslash( $_POST['promotype'] ) ) : '';
        if ( 'eb-banner' === $promotype ) {
            wp_remote_get( 'https://essential-addons.com/essential-blocks-install-gutenberg' );
        }

	    if ( is_wp_error( $result ) ) {
		    wp_send_json_error( $result->get_error_message() );
	    }

        wp_send_json_success(__('Plugin is installed successfully!', 'betterdocs'));
    }

    public function ajax_upgrade_plugin()
    {
        check_ajax_referer('betterdocs-wpdeveloper-plugins', 'security');
        //check user capabilities
        if(!current_user_can( 'update_plugins' )) {
            wp_send_json_error(__('you are not allowed to do this action', 'betterdocs'));
        }

	    $basename = isset( $_POST['basename'] ) ? sanitize_text_field( wp_unslash( $_POST['basename'] ) ) : '';
	    $result   = $this->upgrade_plugin( $basename );

        if (is_wp_error($result)) {
            wp_send_json_error($result->get_error_message());
        }

        wp_send_json_success(__('Plugin is updated successfully!', 'betterdocs'));
    }

    public function ajax_activate_plugin()
    {
        check_ajax_referer('betterdocs-wpdeveloper-plugins', 'security');

        //check user capabilities
        if(!current_user_can( 'activate_plugins' )) {
            wp_send_json_error(__('you are not allowed to do this action', 'betterdocs'));
        }

	    $basename = isset( $_POST['basename'] ) ? sanitize_text_field( wp_unslash( $_POST['basename'] ) ) : '';
	    $result   = activate_plugin( $basename, '', false, true );

	    if ( is_wp_error( $result ) ) {
		    wp_send_json_error( $result->get_error_message() );
	    }

        if ($result === false) {
            wp_send_json_error(__('Plugin couldn\'t be activated.', 'betterdocs'));
        }
        wp_send_json_success(__('Plugin is activated successfully!', 'betterdocs'));
    }

	public function ajax_deactivate_plugin() {
		check_ajax_referer( 'betterdocs-wpdeveloper-plugins', 'security' );

		//check user capabilities
		if ( ! current_user_can( 'activate_plugins' ) ) {
			wp_send_json_error( __( 'you are not allowed to do this action', 'betterdocs' ) );
		}

		$basename = isset( $_POST['basename'] ) ? sanitize_text_field( wp_unslash( $_POST['basename'] ) ) : '';
		deactivate_plugins( $basename, true );

		wp_send_json_success( __( 'Plugin is deactivated successfully!', 'betterdocs' ) );
	}

	public function ajax_auto_active_even_not_installed() {
		check_ajax_referer( 'betterdocs-wpdeveloper-plugins', 'security' );

		$basename = isset( $_POST['basename'] ) ? sanitize_text_field( wp_unslash( $_POST['basename'] ) ) : '';
		if ( $this->get_local_plugin_data( $basename ) === false ) {
			$this->ajax_install_plugin();
		} else {
			$this->ajax_activate_plugin();
		}
	}
}

```
