Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 50
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
PluginUninstaller
0.00% covered (danger)
0.00%
0 / 50
0.00% covered (danger)
0.00%
0 / 6
462
0.00% covered (danger)
0.00%
0 / 1
 uninstall
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
20
 exists
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 is_plugin_installed
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 deactivate_plugin_if_active
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
20
 connect_to_filesystem
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
12
 delete_plugin
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
30
1<?php
2namespace NewfoldLabs\WP\Module\Installer\Services;
3
4use NewfoldLabs\WP\Module\Installer\Data\Plugins;
5
6/**
7 * Class PluginUninstaller
8 * This class is responsible to Uninstall a specified plugin
9 */
10class PluginUninstaller {
11
12    /**
13     * Deactivate a plugin if active and then Uninstall the specific plugin.
14     *
15     * @param string $plugin Plugin URL.
16     * @return \WP_REST_Response|\WP_Error
17     */
18    public static function uninstall( $plugin ) {
19
20        $plugin_list = Plugins::get_squashed();
21        // Gets the specified path for the Plugin from the predefined list
22        $plugin_path = $plugin_list[ $plugin ]['path'];
23
24        if ( isset( $plugin_path ) && self::is_plugin_installed( $plugin_path ) ) {
25
26            self::deactivate_plugin_if_active( $plugin_path );
27            $deleted = self::delete_plugin( $plugin_path );
28
29            // If Deletion is not successful throw an error for a retry.
30            if ( is_wp_error( $deleted ) ) {
31                return $deleted;
32            }
33        }
34
35        return new \WP_REST_Response(
36            array(),
37            201
38        );
39    }
40
41    /**
42     * Checks if a plugin with the given slug exists.
43     *
44     * @param string $plugin Plugin
45     * @return boolean
46     */
47    public static function exists( $plugin ) {
48
49        $plugin_list = Plugins::get_squashed();
50        $plugin_path = $plugin_list[ $plugin ]['path'];
51
52        if ( ! self::is_plugin_installed( $plugin_path ) ) {
53            return false;
54        }
55        return true;
56    }
57
58    /**
59     * Determines if a plugin has already been installed.
60     *
61     * @param string $plugin_path Path to the plugin's header file.
62     * @return boolean
63     */
64    public static function is_plugin_installed( $plugin_path ) {
65        if ( ! function_exists( 'get_plugins' ) ) {
66            require_once ABSPATH . 'wp-admin/includes/plugin.php';
67        }
68        $all_plugins = \get_plugins();
69        if ( ! empty( $all_plugins[ $plugin_path ] ) ) {
70            return true;
71        } else {
72            return false;
73        }
74    }
75
76    /**
77     * Deactivates a Plugin if it is activated.
78     *
79     * @param string $plugin_path Path to the plugin's header file.
80     */
81    public static function deactivate_plugin_if_active( $plugin_path ) {
82
83        // Checks if the necessary functions exist
84        if ( ! function_exists( 'is_plugin_active' ) || ! function_exists( 'deactivate_plugins' ) ) {
85            require_once ABSPATH . 'wp-admin/includes/plugin.php';
86        }
87
88        // Determines whether a plugin is active.
89        if ( \is_plugin_active( $plugin_path ) ) {
90            // Deactivates a single plugin or multiple plugins.
91            // /wp-admin/includes/plugin.php
92            \deactivate_plugins( $plugin_path );
93        }
94    }
95
96    /**
97     * Establishes a connection to the wp_filesystem.
98     *
99     * @return boolean
100     */
101    protected static function connect_to_filesystem() {
102        require_once ABSPATH . 'wp-admin/includes/file.php';
103
104        // We want to ensure that the user has direct access to the filesystem.
105        $access_type = \get_filesystem_method();
106        if ( 'direct' !== $access_type ) {
107            return false;
108        }
109
110        $creds = \request_filesystem_credentials( site_url() . '/wp-admin', '', false, false, array() );
111
112        if ( ! \WP_Filesystem( $creds ) ) {
113            return false;
114        }
115
116        return true;
117    }
118
119    /**
120     * Deletes a Plugin if it exists.
121     *
122     * @param string $plugin_path Path to the plugin's header file.
123     * @return boolean|\WP_Error
124     */
125    public static function delete_plugin( $plugin_path ) {
126
127        // Checks if the necessary functions exist
128        if ( ! function_exists( 'delete_plugins' ) ) {
129            require_once ABSPATH . 'wp-admin/includes/plugin.php';
130        }
131
132        if ( ! self::connect_to_filesystem() ) {
133            return new \WP_Error(
134                'nfd_installer_error',
135                'Could not connect to the filesystem.',
136                array( 'status' => 500 )
137            );
138        }
139
140        // Removes directory and files of a plugin
141        $deleted = \delete_plugins( array( $plugin_path ) );
142        if ( ! $deleted || is_wp_error( $deleted ) ) {
143            return new \WP_Error(
144                'nfd_installer_error',
145                'Unable to Delete the Plugin',
146                array( 'status' => 500 )
147            );
148        }
149
150        return true;
151    }
152}