PluginProbe
UpdraftPlus: WP Backup & Migration Plugin / 1.16.5
UpdraftPlus: WP Backup & Migration Plugin v1.16.5
1.26.7 1.26.6 1.26.5 1.26.4 1.26.3 1.9.19 1.9.25 1.9.26 1.9.30 1.9.31 1.9.32 1.9.4 1.9.40 1.9.41 1.9.42 1.9.43 1.9.44 1.9.45 1.9.46 1.9.5 1.9.50 1.9.51 1.9.60 1.9.62 1.9.63 All 371 releases
updraftplus / central / modules / plugin.php

plugin.php in UpdraftPlus: WP Backup & Migration Plugin 1.16.5, at central/modules/plugin.php

510 lines 15.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if (!defined('UPDRAFTPLUS_DIR')) die('No access.');
4
5 /**
6 * Handles UpdraftCentral Plugin Commands which basically handles
7 * the installation and activation of a plugin
8 */
9 class UpdraftCentral_Plugin_Commands extends UpdraftCentral_Commands {
10
11 private $switched = false;
12
13 /**
14 * Function that gets called before every action
15 *
16 * @param string $command a string that corresponds to UDC command to call a certain method for this class.
17 * @param array $data an array of data post or get fields
18 * @param array $extra_info extrainfo use in the udrpc_action, e.g. user_id
19 *
20 * link to udrpc_action main function in class UpdraftPlus_UpdraftCentral_Listener
21 */
22 public function _pre_action($command, $data, $extra_info) {// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found
23 // Here we assign the current blog_id to a variable $blog_id
24 $blog_id = get_current_blog_id();
25 if (!empty($data['site_id'])) $blog_id = $data['site_id'];
26
27 if (function_exists('switch_to_blog') && is_multisite() && $blog_id) {
28 $this->switched = switch_to_blog($blog_id);
29 }
30 }
31
32 /**
33 * Function that gets called after every action
34 *
35 * @param string $command a string that corresponds to UDC command to call a certain method for this class.
36 * @param array $data an array of data post or get fields
37 * @param array $extra_info extrainfo use in the udrpc_action, e.g. user_id
38 *
39 * link to udrpc_action main function in class UpdraftPlus_UpdraftCentral_Listener
40 */
41 public function _post_action($command, $data, $extra_info) {// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found
42 // Here, we're restoring to the current (default) blog before we switched
43 if ($this->switched) restore_current_blog();
44 }
45
46 /**
47 * Constructor
48 */
49 public function __construct() {
50 $this->_admin_include('plugin.php', 'file.php', 'template.php', 'class-wp-upgrader.php', 'plugin-install.php', 'update.php');
51 }
52
53 /**
54 * Checks whether the plugin is currently installed and activated.
55 *
56 * @param array $query Parameter array containing the name of the plugin to check
57 * @return array Contains the result of the current process
58 */
59 public function is_plugin_installed($query) {
60
61 if (!isset($query['plugin']))
62 return $this->_generic_error_response('plugin_name_required');
63
64
65 $result = $this->_get_plugin_info($query['plugin']);
66 return $this->_response($result);
67 }
68
69 /**
70 * Applies currently requested action for plugin processing
71 *
72 * @param string $action The action to apply (e.g. activate or install)
73 * @param array $query Parameter array containing information for the currently requested action
74 *
75 * @return array
76 */
77 private function _apply_plugin_action($action, $query) {
78
79 $result = array();
80 switch ($action) {
81 case 'activate':
82 case 'network_activate':
83 $info = $this->_get_plugin_info($query['plugin']);
84 if ($info['installed']) {
85 if (is_multisite() && 'network_activate' === $action) {
86 $activate = activate_plugin($info['plugin_path'], '', true);
87 } else {
88 $activate = activate_plugin($info['plugin_path']);
89 }
90
91 if (is_wp_error($activate)) {
92 $result = $this->_generic_error_response('generic_response_error', array($activate->get_error_message()));
93 } else {
94 $result = array('activated' => true);
95 }
96 } else {
97 $result = $this->_generic_error_response('plugin_not_installed', array($query['plugin']));
98 }
99 break;
100 case 'deactivate':
101 case 'network_deactivate':
102 $info = $this->_get_plugin_info($query['plugin']);
103 if ($info['active']) {
104 if (is_multisite() && 'network_deactivate' === $action) {
105 deactivate_plugins($info['plugin_path'], false, true);
106 } else {
107 deactivate_plugins($info['plugin_path']);
108 }
109
110 if (!is_plugin_active($info['plugin_path'])) {
111 $result = array('deactivated' => true);
112 } else {
113 $result = $this->_generic_error_response('deactivate_plugin_failed', array($query['plugin']));
114 }
115 } else {
116 $result = $this->_generic_error_response('not_active', array($query['plugin']));
117 }
118 break;
119 case 'install':
120 $api = plugins_api('plugin_information', array(
121 'slug' => $query['slug'],
122 'fields' => array(
123 'short_description' => false,
124 'sections' => false,
125 'requires' => false,
126 'rating' => false,
127 'ratings' => false,
128 'downloaded' => false,
129 'last_updated' => false,
130 'added' => false,
131 'tags' => false,
132 'compatibility' => false,
133 'homepage' => false,
134 'donate_link' => false,
135 )
136 ));
137
138 if (is_wp_error($api)) {
139 $result = $this->_generic_error_response('generic_response_error', array($api->get_error_message()));
140 } else {
141 $info = $this->_get_plugin_info($query['plugin']);
142 $installed = $info['installed'];
143
144 if (!$installed) {
145 // WP < 3.7
146 if (!class_exists('Automatic_Upgrader_Skin')) include_once(UPDRAFTPLUS_DIR.'/central/classes/class-automatic-upgrader-skin.php');
147
148 $skin = new Automatic_Upgrader_Skin();
149 $upgrader = new Plugin_Upgrader($skin);
150
151 $download_link = $api->download_link;
152 $installed = $upgrader->install($download_link);
153 }
154
155 if (!$installed) {
156 $result = $this->_generic_error_response('plugin_install_failed', array($query['plugin']));
157 } else {
158 $result = array('installed' => true);
159 }
160 }
161 break;
162 }
163
164 return $result;
165 }
166
167 /**
168 * Preloads the submitted credentials to the global $_POST variable
169 *
170 * @param array $query Parameter array containing information for the currently requested action
171 */
172 private function _preload_credentials($query) {
173 if (!empty($query) && isset($query['filesystem_credentials'])) {
174 parse_str($query['filesystem_credentials'], $filesystem_credentials);
175 if (is_array($filesystem_credentials)) {
176 foreach ($filesystem_credentials as $key => $value) {
177 // Put them into $_POST, which is where request_filesystem_credentials() checks for them.
178 $_POST[$key] = $value;
179 }
180 }
181 }
182 }
183
184 /**
185 * Checks whether we have the required fields submitted and the user has
186 * the capabilities to execute the requested action
187 *
188 * @param array $query The submitted information
189 * @param array $fields The required fields to check
190 * @param array $capabilities The capabilities to check and validate
191 *
192 * @return array|string
193 */
194 private function _validate_fields_and_capabilities($query, $fields, $capabilities) {
195
196 $error = '';
197 if (!empty($fields)) {
198 for ($i=0; $i<count($fields); $i++) {
199 $field = $fields[$i];
200
201 if (!isset($query[$field])) {
202 if ('keyword' === $field) {
203 $error = $this->_generic_error_response('keyword_required');
204 } else {
205 $error = $this->_generic_error_response('plugin_'.$query[$field].'_required');
206 }
207 break;
208 }
209 }
210 }
211
212 if (empty($error) && !empty($capabilities)) {
213 for ($i=0; $i<count($capabilities); $i++) {
214 if (!current_user_can($capabilities[$i])) {
215 $error = $this->_generic_error_response('plugin_insufficient_permission');
216 break;
217 }
218 }
219 }
220
221 return $error;
222 }
223
224 /**
225 * Activates the plugin
226 *
227 * @param array $query Parameter array containing the name of the plugin to activate
228 * @return array Contains the result of the current process
229 */
230 public function activate_plugin($query) {
231
232 $error = $this->_validate_fields_and_capabilities($query, array('plugin'), array('activate_plugins'));
233 if (!empty($error)) {
234 return $error;
235 }
236
237 $action = 'activate';
238 if (!empty($query['multisite']) && (bool) $query['multisite']) $action = 'network_'.$action;
239
240 $result = $this->_apply_plugin_action($action, $query);
241 if (empty($result['activated'])) {
242 return $result;
243 }
244
245 return $this->_response($result);
246 }
247
248 /**
249 * Deactivates the plugin
250 *
251 * @param array $query Parameter array containing the name of the plugin to deactivate
252 * @return array Contains the result of the current process
253 */
254 public function deactivate_plugin($query) {
255
256 $error = $this->_validate_fields_and_capabilities($query, array('plugin'), array('activate_plugins'));
257 if (!empty($error)) {
258 return $error;
259 }
260
261 $action = 'deactivate';
262 if (!empty($query['multisite']) && (bool) $query['multisite']) $action = 'network_'.$action;
263
264 $result = $this->_apply_plugin_action($action, $query);
265 if (empty($result['deactivated'])) {
266 return $result;
267 }
268
269 return $this->_response($result);
270 }
271
272 /**
273 * Download, install and activates the plugin
274 *
275 * @param array $query Parameter array containing the filesystem credentials entered by the user along with the plugin name and slug
276 * @return array Contains the result of the current process
277 */
278 public function install_activate_plugin($query) {
279
280 $error = $this->_validate_fields_and_capabilities($query, array('plugin', 'slug'), array('install_plugins', 'activate_plugins'));
281 if (!empty($error)) {
282 return $error;
283 }
284
285 $this->_preload_credentials($query);
286
287 $result = $this->_apply_plugin_action('install', $query);
288 if (!empty($result['installed']) && $result['installed']) {
289 $action = 'activate';
290 if (!empty($query['multisite']) && (bool) $query['multisite']) $action = 'network_'.$action;
291
292 $result = $this->_apply_plugin_action($action, $query);
293 if (empty($result['activated'])) {
294 return $result;
295 }
296 } else {
297 return $result;
298 }
299
300 return $this->_response($result);
301 }
302
303 /**
304 * Download, install the plugin
305 *
306 * @param array $query Parameter array containing the filesystem credentials entered by the user along with the plugin name and slug
307 * @return array Contains the result of the current process
308 */
309 public function install_plugin($query) {
310
311 $error = $this->_validate_fields_and_capabilities($query, array('plugin', 'slug'), array('install_plugins'));
312 if (!empty($error)) {
313 return $error;
314 }
315
316 $this->_preload_credentials($query);
317
318 $result = $this->_apply_plugin_action('install', $query);
319 if (empty($result['installed'])) {
320 return $result;
321 }
322
323 return $this->_response($result);
324 }
325
326 /**
327 * Uninstall/delete the plugin
328 *
329 * @param array $query Parameter array containing the filesystem credentials entered by the user along with the plugin name and slug
330 * @return array Contains the result of the current process
331 */
332 public function delete_plugin($query) {
333
334 $error = $this->_validate_fields_and_capabilities($query, array('plugin'), array('delete_plugins'));
335 if (!empty($error)) {
336 return $error;
337 }
338
339 $this->_preload_credentials($query);
340 $info = $this->_get_plugin_info($query['plugin']);
341
342 if ($info['installed']) {
343 $deleted = delete_plugins(array($info['plugin_path']));
344
345 if ($deleted) {
346 $result = array('deleted' => true);
347 } else {
348 $result = $this->_generic_error_response('delete_plugin_failed', array($query['plugin']));
349 }
350 } else {
351 $result = $this->_generic_error_response('plugin_not_installed', array($query['plugin']));
352 }
353
354 return $this->_response($result);
355 }
356
357 /**
358 * Updates/upgrade the plugin
359 *
360 * @param array $query Parameter array containing the filesystem credentials entered by the user along with the plugin name and slug
361 * @return array Contains the result of the current process
362 */
363 public function update_plugin($query) {
364
365 $error = $this->_validate_fields_and_capabilities($query, array('plugin', 'slug'), array('update_plugins'));
366 if (!empty($error)) {
367 return $error;
368 }
369
370 $this->_preload_credentials($query);
371 $info = $this->_get_plugin_info($query['plugin']);
372
373 // Make sure that we still have the plugin installed before running
374 // the update process
375 if ($info['installed']) {
376 // Load the updates command class if not existed
377 if (!class_exists('UpdraftCentral_Updates_Commands')) include_once('updates.php');
378 $update_command = new UpdraftCentral_Updates_Commands($this->rc);
379
380 $result = $update_command->update_plugin($info['plugin_path'], $query['slug']);
381 if (!empty($result['error'])) {
382 $result['values'] = array($query['plugin']);
383 }
384 } else {
385 $result = $this->_generic_error_response('plugin_not_installed', array($query['plugin']));
386 }
387
388 return $this->_response($result);
389 }
390
391 /**
392 * Gets the plugin information along with its active and install status
393 *
394 * @internal
395 * @param array $plugin The name of the plugin to pull the information from
396 * @return array Contains the plugin information
397 */
398 private function _get_plugin_info($plugin) {
399
400 $info = array(
401 'active' => false,
402 'installed' => false
403 );
404
405 // Clear plugin cache so that newly installed/downloaded plugins
406 // gets reflected when calling "get_plugins"
407 wp_clean_plugins_cache();
408
409 // Gets all plugins available.
410 $get_plugins = get_plugins();
411
412 // Loops around each plugin available.
413 foreach ($get_plugins as $key => $value) {
414 // If the plugin name matches that of the specified name, it will gather details.
415 if ($value['Name'] === $plugin) {
416 $info['installed'] = true;
417 $info['active'] = is_plugin_active($key);
418 $info['plugin_path'] = $key;
419 $info['data'] = $value;
420 break;
421 }
422 }
423
424 return $info;
425 }
426
427 /**
428 * Loads all available plugins with additional attributes and settings needed by UpdraftCentral
429 *
430 * @param array $query Parameter array Any available parameters needed for this action
431 * @return array Contains the result of the current process
432 */
433 public function load_plugins($query) {
434
435 $error = $this->_validate_fields_and_capabilities($query, array(), array('install_plugins', 'activate_plugins'));
436 if (!empty($error)) {
437 return $error;
438 }
439
440 $website = get_bloginfo('name');
441 $results = array();
442
443 // Load the updates command class if not existed
444 if (!class_exists('UpdraftCentral_Updates_Commands')) include_once('updates.php');
445 $updates = new UpdraftCentral_Updates_Commands($this->rc);
446
447 // Get plugins for update
448 $plugin_updates = $updates->get_item_updates('plugins');
449
450 // Get all plugins
451 $plugins = get_plugins();
452
453 foreach ($plugins as $key => $value) {
454 $slug = basename($key, '.php');
455
456 $plugin = new stdClass();
457 $plugin->name = $value['Name'];
458 $plugin->description = $value['Description'];
459 $plugin->slug = $slug;
460 $plugin->version = $value['Version'];
461 $plugin->author = $value['Author'];
462 $plugin->status = is_plugin_active($key) ? 'active' : 'inactive';
463 $plugin->website = $website;
464 $plugin->multisite = is_multisite();
465
466 if (!empty($plugin_updates[$key])) {
467 $update_info = $plugin_updates[$key];
468
469 if (version_compare($update_info->Version, $update_info->update->new_version, '<')) {
470 if (!empty($update_info->update->new_version)) $plugin->latest_version = $update_info->update->new_version;
471 if (!empty($update_info->update->package)) $plugin->download_link = $update_info->update->package;
472 if (!empty($update_info->update->sections)) $plugin->sections = $update_info->update->sections;
473 }
474 }
475
476 if (empty($plugin->short_description) && !empty($plugin->description)) {
477 // Only pull the first sentence as short description, it should be enough rather than displaying
478 // an empty description or a full blown one which the user can access anytime if they press on
479 // the view details link in UpdraftCentral.
480 $temp = explode('.', $plugin->description);
481 $short_description = $temp[0];
482
483 // Adding the second sentence wouldn't hurt, in case the first sentence is too short.
484 if (isset($temp[1])) $short_description .= '.'.$temp[1];
485
486 $plugin->short_description = $short_description.'.';
487 }
488
489 $results[] = $plugin;
490 }
491
492 $result = array(
493 'plugins' => $results
494 );
495
496 $result = array_merge($result, $this->_get_backup_credentials_settings(WP_PLUGIN_DIR));
497 return $this->_response($result);
498 }
499
500 /**
501 * Gets the backup and security credentials settings for this website
502 *
503 * @param array $query Parameter array Any available parameters needed for this action
504 * @return array Contains the result of the current process
505 */
506 public function get_plugin_requirements() {
507 return $this->_response($this->_get_backup_credentials_settings(WP_PLUGIN_DIR));
508 }
509 }
510