Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 218
0.00% covered (danger)
0.00%
0 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
PluginsController
0.00% covered (danger)
0.00%
0 / 218
0.00% covered (danger)
0.00%
0 / 8
870
0.00% covered (danger)
0.00%
0 / 1
 register_routes
0.00% covered (danger)
0.00%
0 / 47
0.00% covered (danger)
0.00%
0 / 1
2
 get_approved_plugins
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 get_install_plugin_args
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 1
2
 get_uninstall_plugin_args
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
2
 get_status_args
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
2
 install
0.00% covered (danger)
0.00%
0 / 54
0.00% covered (danger)
0.00%
0 / 1
210
 uninstall
0.00% covered (danger)
0.00%
0 / 30
0.00% covered (danger)
0.00%
0 / 1
30
 get_status
0.00% covered (danger)
0.00%
0 / 33
0.00% covered (danger)
0.00%
0 / 1
30
1<?php
2namespace NewfoldLabs\WP\Module\Installer\RestApi;
3
4use NewfoldLabs\WP\Module\Installer\Data\Options;
5use NewfoldLabs\WP\Module\Installer\Permissions;
6use NewfoldLabs\WP\Module\Installer\Data\Plugins;
7use NewfoldLabs\WP\Module\Installer\Services\PluginInstaller;
8use NewfoldLabs\WP\Module\Installer\Services\PluginUninstaller;
9use NewfoldLabs\WP\Module\Installer\Tasks\PluginInstallTask;
10use NewfoldLabs\WP\Module\Installer\TaskManagers\PluginInstallTaskManager;
11use NewfoldLabs\WP\Module\Installer\Tasks\PluginUninstallTask;
12use NewfoldLabs\WP\Module\Installer\TaskManagers\PluginUninstallTaskManager;
13
14/**
15 * Class PluginsController
16 */
17class PluginsController {
18    /**
19     * The namespace of this controller's route.
20     *
21     * @var string
22     */
23    protected $namespace = 'newfold-installer/v1';
24
25    /**
26     * The base of this controller's route.
27     *
28     * @var string
29     */
30    protected $rest_base = '/plugins';
31
32    /**
33     * Registers rest routes for PluginsController class.
34     *
35     * @return void
36     */
37    public function register_routes() {
38        \register_rest_route(
39            $this->namespace,
40            $this->rest_base . '/approved',
41            array(
42                array(
43                    'methods'             => \WP_REST_Server::READABLE,
44                    'callback'            => array( $this, 'get_approved_plugins' ),
45                    'permission_callback' => array( Permissions::class, 'rest_is_authorized_admin' ),
46                ),
47            )
48        );
49
50        \register_rest_route(
51            $this->namespace,
52            $this->rest_base . '/install',
53            array(
54                array(
55                    'methods'             => \WP_REST_Server::CREATABLE,
56                    'callback'            => array( $this, 'install' ),
57                    'args'                => $this->get_install_plugin_args(),
58                    'permission_callback' => array( PluginInstaller::class, 'check_install_permissions' ),
59                ),
60            )
61        );
62
63        \register_rest_route(
64            $this->namespace,
65            $this->rest_base . '/uninstall',
66            array(
67                array(
68                    'methods'             => \WP_REST_Server::CREATABLE,
69                    'callback'            => array( $this, 'uninstall' ),
70                    'args'                => $this->get_install_plugin_args(),
71                    'permission_callback' => array( PluginInstaller::class, 'check_install_permissions' ),
72                ),
73            )
74        );
75
76        \register_rest_route(
77            $this->namespace,
78            $this->rest_base . '/status',
79            array(
80                array(
81                    'methods'             => \WP_REST_Server::READABLE,
82                    'callback'            => array( $this, 'get_status' ),
83                    'args'                => $this->get_status_args(),
84                    'permission_callback' => array( Permissions::class, 'rest_is_authorized_admin' ),
85                ),
86            )
87        );
88    }
89
90    /**
91     * Get approved plugin slugs, urls and domains.
92     *
93     * @return \WP_REST_Response
94     */
95    public function get_approved_plugins() {
96
97        return new \WP_REST_Response(
98            Plugins::get_approved(),
99            200
100        );
101    }
102
103    /**
104     * Get args for the install route.
105     *
106     * @return array
107     */
108    public function get_install_plugin_args() {
109        return array(
110            'plugin'   => array(
111                'type'     => 'string',
112                'required' => true,
113            ),
114            'activate' => array(
115                'type'    => 'boolean',
116                'default' => false,
117            ),
118            'queue'    => array(
119                'type'    => 'boolean',
120                'default' => true,
121            ),
122            'priority' => array(
123                'type'    => 'integer',
124                'default' => 0,
125            ),
126            'premium'  => array(
127                'type'    => 'boolean',
128                'default' => false,
129            ),
130            'provider' => array(
131                'type'    => 'string',
132                'default' => '',
133            ),
134        );
135    }
136
137    /**
138     * Get args for the uninstall route.
139     *
140     * @return array
141     */
142    public function get_uninstall_plugin_args() {
143        return array(
144            'plugin'   => array(
145                'type'     => 'string',
146                'required' => true,
147            ),
148            'queue'    => array(
149                'type'    => 'boolean',
150                'default' => true,
151            ),
152            'priority' => array(
153                'type'    => 'integer',
154                'default' => 0,
155            ),
156        );
157    }
158
159    /**
160     * Get the plugin status check arguments.
161     *
162     * @return array
163     */
164    public function get_status_args() {
165        return array(
166            'plugin'    => array(
167                'type'     => 'string',
168                'required' => true,
169            ),
170            'activated' => array(
171                'type'    => 'boolean',
172                'default' => true,
173            ),
174        );
175    }
176
177    /**
178     * Install the requested plugin via a zip url (or) slug.
179     *
180     * @param \WP_REST_Request $request the incoming request object.
181     *
182     * @return \WP_REST_Response|\WP_Error
183     */
184    public function install( \WP_REST_Request $request ) {
185        $plugin   = $request->get_param( 'plugin' );
186        $queue    = $request->get_param( 'queue' );
187        $priority = $request->get_param( 'priority' );
188        $provider = $request->get_param( 'provider' );
189        $premium  =
190            $request->get_param( 'premium' )
191            ? $request->get_param( 'premium' )
192            : false; // defaults to false
193        $basename =
194            $request->get_param( 'basename' )
195            ? $request->get_param( 'basename' )
196            : false; // defaults to false
197
198        // default to true
199        $shoud_activate =
200            $request->get_param( 'activate' )
201            ? $request->get_param( 'activate' )
202            : true; // default
203
204        // If basename is provided, check if installed or active already.
205        if ( $basename && PluginInstaller::is_plugin_installed( $basename ) ) {
206            // If already installed, check if already active
207            if ( \is_plugin_active( $basename ) ) {
208                // If already active, nothing to do, return 200
209                return new \WP_REST_Response(
210                    array(),
211                    200
212                );
213            }
214            // If not active, check if should activate
215            if ( $shoud_activate ) {
216                // If should activate, activate the plugin
217                $status = \activate_plugin( $basename );
218                if ( \is_wp_error( $status ) ) {
219                    $status->add_data( array( 'status' => 500 ) );
220                    return $status;
221                }
222                return new \WP_REST_Response(
223                    array(),
224                    200
225                );
226            }
227        }
228
229        // If the plugin is premium use the corresponding function.
230        if ( true === $premium ) {
231            return PluginInstaller::install_premium_plugin( $plugin, $provider, $shoud_activate, $basename );
232        }
233
234        // If the plugin is free and not queued use the corresponding function.
235        if ( false === $premium && false === $queue ) {
236            return PluginInstaller::install( $plugin, $shoud_activate );
237        }
238
239        // Checks if a plugin with the given slug and activation criteria already exists.
240        if ( PluginInstaller::exists( $plugin, $shoud_activate ) ) {
241            return new \WP_REST_Response(
242                array(),
243                200
244            );
245        }
246
247        // Queue the plugin install if specified in the request.
248        if ( $queue ) {
249            // Add a new PluginInstallTask to the Plugin install queue.
250            PluginInstallTaskManager::add_to_queue(
251                new PluginInstallTask(
252                    $plugin,
253                    $shoud_activate,
254                    $priority
255                )
256            );
257
258            return new \WP_REST_Response(
259                array(),
260                202
261            );
262        }
263
264        // Set up the task if it need not be queued.
265        $plugin_install_task = new PluginInstallTask( $plugin, $shoud_activate );
266
267        // Return the queued task.
268        return $plugin_install_task->execute();
269    }
270
271    /**
272     * Handle an uninstall requuest.
273     *
274     * @param \WP_REST_Request $request The incoming request object.
275     * @return \WP_REST_Response
276     */
277    public function uninstall( \WP_REST_Request $request ) {
278        $plugin   = $request->get_param( 'plugin' );
279        $queue    = $request->get_param( 'queue' );
280        $priority = $request->get_param( 'priority' );
281
282        $position_in_queue = PluginInstallTaskManager::status( $plugin );
283        if ( false !== $position_in_queue && 0 !== $position_in_queue ) {
284            PluginInstallTaskManager::remove_from_queue(
285                $plugin
286            );
287
288            return new \WP_REST_Response(
289                array(),
290                200
291            );
292        }
293
294        if ( ! PluginUninstaller::exists( $plugin ) ) {
295            return new \WP_REST_Response(
296                array(),
297                200
298            );
299        }
300
301        // Queue the plugin uninstall if specified in the request.
302        if ( $queue ) {
303            // Add a new PluginUninstallTask to the Plugin install queue.
304            PluginUninstallTaskManager::add_to_queue(
305                new PluginUninstallTask(
306                    $plugin,
307                    $priority
308                )
309            );
310
311            return new \WP_REST_Response(
312                array(),
313                202
314            );
315        }
316
317        // Execute the task if it need not be queued.
318        $plugin_uninstall_task = new PluginUninstallTask( $plugin );
319
320        return $plugin_uninstall_task->execute();
321    }
322
323    /**
324     * Returns the status of a given plugin slug.
325     *
326     * @param \WP_REST_Request $request the incoming request object.
327     * @return \WP_REST_Response
328     */
329    public function get_status( \WP_REST_Request $request ) {
330        $plugin       = $request->get_param( 'plugin' );
331        $is_activated = $request->get_param( 'activated' );
332
333        if ( PluginInstaller::exists( $plugin, $is_activated ) ) {
334            return new \WP_REST_Response(
335                array(
336                    'status' => $is_activated ? 'activated' : 'installed',
337                ),
338                200
339            );
340        }
341
342        $position_in_queue = PluginInstallTaskManager::status( $plugin );
343
344        if ( false !== $position_in_queue ) {
345            return new \WP_REST_Response(
346                array(
347                    'status'   => 'installing',
348                    'estimate' => ( ( $position_in_queue + 1 ) * 30 ),
349                ),
350                200
351            );
352        }
353
354        $in_progress_plugin = \get_option( Options::get_option_name( 'plugins_init_status' ), '' );
355        if ( $in_progress_plugin === $plugin ) {
356            return new \WP_REST_Response(
357                array(
358                    'status'   => 'installing',
359                    'estimate' => 30,
360                ),
361                200
362            );
363        }
364
365        return new \WP_REST_Response(
366            array(
367                'status' => 'inactive',
368            ),
369            200
370        );
371    }
372}