PluginProbe
Adminify – White Label, Admin Menu Editor, Login Customizer / 4.2.25
Adminify – White Label, Admin Menu Editor, Login Customizer v4.2.25
4.3.1 4.3.0 4.2.26 4.2.25 4.2.24 4.2.23 4.2.22 4.2.21 4.2.20 4.2.19 4.2.18 4.2.17 4.2.16 4.2.15 4.2.14 4.2.13 4.2.12 4.2.11 4.2.10 4.2.9 4.2.8 4.2.7 4.2.6 4.2.5 4.1.17 All 164 releases
adminify / Libs / Addons.php

Addons.php in Adminify – White Label, Admin Menu Editor, Login Customizer 4.2.25, at Libs/Addons.php

825 lines 36.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace PXLBSAdminify\Libs;
4
5 // No, Direct access Sir !!!
6 if (!defined('ABSPATH')) {
7 exit;
8 }
9
10 /*
11 * Addons global class
12 */
13
14 if (!class_exists('Addons')) {
15
16 /**
17 * Addons Class
18 *
19 * Jewel Theme <support@jeweltheme.com>
20 */
21 class Addons
22 {
23 public $menu_items = [];
24 public $plugins_list = [];
25 public $sub_menu;
26 public $menu_order;
27
28
29 /**
30 * Constructor method
31 *
32 * @param integer $menu_order .
33 * @author Jewel Theme <support@jeweltheme.com>
34 */
35 public function __construct($menu_order = 70)
36 {
37 $this->menu_order = $menu_order;
38 $this->menu_items = $this->menu_items();
39 $this->plugins_list = $this->plugins_list();
40
41 $this->includes();
42
43 // Show Addons menu only on network admin for multisite, or on regular admin for single site
44 if ( is_multisite() ) {
45 add_action('network_admin_menu', array($this, 'admin_menu'), 1000);
46 } else {
47 add_action('admin_menu', array($this, 'admin_menu'), 1000);
48 }
49 add_action('wp_ajax_pxlbsadminify_addons_upgrade_plugin', array($this, 'pxlbsadminify_addons_upgrade_plugin'));
50 add_action('wp_ajax_pxlbsadminify_addons_activate_plugin', array($this, 'pxlbsadminify_addons_activate_plugin'));
51 // Notify the site admin when a renamed legacy addon is detected
52 // alongside its replacement. Per WordPress.org plugin guidelines,
53 // we must not deactivate or activate plugins automatically; the
54 // user has to perform the swap themselves from the Plugins screen.
55 add_action('admin_notices', array($this, 'maybe_renamed_addon_notice'));
56 add_action( 'rest_api_init', array( $this , 'addons_rest_routes') );
57 }
58
59 public function addons_rest_routes() {
60 register_rest_route('adminify/v1', '/get-addons-list', array(
61 'methods' => 'GET',
62 'callback' => [$this, 'get_addons_plugins_list'],
63 'permission_callback' => [$this, 'check_is_admin_user'],
64 ));
65
66 register_rest_route('adminify/v1', '/install-addons', array(
67 'methods' => 'POST',
68 'callback' => [$this, 'install_addons'],
69 'permission_callback' => [$this, 'check_verify_nonce_and_permissions'],
70 ));
71 }
72
73 public function check_is_admin_user() {
74 if ( is_multisite() && ! is_super_admin() ) {
75 return new \WP_Error('rest_forbidden', __('You are not allowed to access this resource.', 'adminify'), array('status' => 403));
76 }
77 if ( ! current_user_can('manage_options') ) {
78 return new \WP_Error('rest_forbidden', __('You are not allowed to access this resource.', 'adminify'), array('status' => 403));
79 }
80 return true;
81 }
82
83 public function check_verify_nonce_and_permissions() {
84 // The install-addons endpoint may both install AND activate
85 // addons depending on each addon's current status, so the
86 // caller must hold BOTH capabilities. On multisite this also
87 // requires super admin.
88 if ( is_multisite() && ! is_super_admin() ) {
89 return new \WP_Error('rest_forbidden', __('Super admin required.', 'adminify'), array('status' => 403));
90 }
91 if ( ! current_user_can('install_plugins') ) {
92 return new \WP_Error('rest_forbidden', __('You are not allowed to install plugins.', 'adminify'), array('status' => 403));
93 }
94 if ( ! current_user_can('activate_plugins') ) {
95 return new \WP_Error('rest_forbidden', __('You are not allowed to activate plugins.', 'adminify'), array('status' => 403));
96 }
97
98 // Nonce check from header. Sanitize and unslash before verifying.
99 $nonce = isset($_SERVER['HTTP_X_WP_NONCE'])
100 ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_WP_NONCE'] ) )
101 : '';
102 if ( ! wp_verify_nonce( $nonce, 'wp_rest' ) ) {
103 return new \WP_Error('rest_cookie_invalid_nonce', __('Invalid nonce.', 'adminify'), array('status' => 403));
104 }
105
106 return true;
107 }
108
109
110 public function get_addons_plugins_list() {
111 // Fetch the catalogue on demand. This callback only runs on the
112 // Add-ons page (a user action), so the remote request is not made on
113 // routine admin page loads.
114 $plugins = ( method_exists( $this, 'get_adminify_plugins_lists' ) )
115 ? (array) $this->get_adminify_plugins_lists()
116 : (array) $this->plugins_list;
117 unset($plugins['master-addons']);
118 $all_plugins = get_plugins();
119 $active_plugins = get_option('active_plugins');
120 foreach( $plugins as $slug => $plugin){
121 foreach ($all_plugins as $plugin_file => $plugin_data) {
122 if (strpos($plugin_file, $slug) !== false) {
123 $plugins[$slug]["status"] = 'installed';
124
125 if (in_array($plugin_file, $active_plugins)) {
126 $plugins[$slug]["status"] = 'activated';
127 }
128 break;
129 }
130 }
131 if( !isset($plugins[$slug]["status"])) $plugins[$slug]["status"] = 'not-installed';
132
133 }
134
135 return rest_ensure_response($plugins);
136
137 }
138
139
140 public function install_addons( $request ) {
141 $addons = $request->get_param('addons');
142 if ( empty($addons) || ! is_array($addons) ) {
143 return new \WP_Error('no_addons', __('No addons were selected.', 'adminify'), array('status' => 400));
144 }
145
146 $plugins_list = $this->get_addons_plugins_list()->data;
147 foreach( $addons as $key => $plugin ) {
148 $plugin = sanitize_key( $plugin );
149 if ( ! isset( $plugins_list[ $plugin ] ) ) {
150 continue;
151 }
152 if ( $plugins_list[ $plugin ]['status'] === 'activated' ) {
153 continue;
154 }
155 if ( $plugins_list[ $plugin ]['status'] === 'installed' ) {
156 $this->activate_plugin_by_slug( $plugin );
157 continue;
158 }
159 $params = [
160 'request_type' => 'rest',
161 'plugin' => $plugins_list[ $plugin ]['download_link'],
162 ];
163
164 $this->pxlbsadminify_addons_upgrade_plugin( $params );
165 }
166
167 return rest_ensure_response(['message' => __('Addons processed.', 'adminify'), 'addons' => $addons]);
168 }
169
170 function activate_plugin_by_slug($slug) {
171 // Activation requires the activate_plugins capability in
172 // addition to whatever capability gated the calling endpoint.
173 // On multisite, activation must be performed by a super admin.
174 if ( is_multisite() && ! is_super_admin() ) {
175 return new \WP_Error( 'rest_forbidden', __( 'Super admin required to activate plugins.', 'adminify' ), array( 'status' => 403 ) );
176 }
177 if ( ! current_user_can( 'activate_plugins' ) ) {
178 return new \WP_Error( 'rest_forbidden', __( 'You are not allowed to activate plugins.', 'adminify' ), array( 'status' => 403 ) );
179 }
180
181 // Reject any slug containing path separators / traversal so
182 // $slug cannot escape WP_PLUGIN_DIR.
183 if ( ! is_string( $slug ) || $slug === '' || strpbrk( $slug, "/\\" ) !== false || strpos( $slug, '..' ) !== false ) {
184 return new \WP_Error( 'invalid_slug', __( 'Invalid plugin slug.', 'adminify' ), array( 'status' => 400 ) );
185 }
186
187 // Slug must be present in the trusted addons list.
188 if ( ! array_key_exists( $slug, (array) $this->plugins_list ) ) {
189 return new \WP_Error( 'invalid_slug', __( 'Invalid plugin slug.', 'adminify' ), array( 'status' => 400 ) );
190 }
191
192 $plugin_path = WP_PLUGIN_DIR . '/' . $slug;
193
194 if ( ! is_dir( $plugin_path ) ) {
195 return;
196 }
197
198 $installed_plugins = get_plugins( '/' . $slug );
199 if ( empty( $installed_plugins ) ) {
200 return;
201 }
202
203 $plugin_relative_path = $slug . '/' . key( $installed_plugins );
204
205 if ( is_plugin_active( $plugin_relative_path ) ) {
206 return;
207 }
208
209 activate_plugin( $plugin_relative_path );
210 }
211
212 /**
213 * Map of legacy addon slugs that have been renamed to a new slug.
214 *
215 * @return array<string,string>
216 */
217 protected function renamed_addons_map() {
218 return [
219 'sidebar-generator/adminify-sidebar-generator.php' => 'adminify-sidebar-generator/adminify-sidebar-generator.php',
220 ];
221 }
222
223 /**
224 * Show a non-blocking admin notice if a legacy (renamed) addon is
225 * still installed. We never deactivate or activate plugins on the
226 * user's behalf; the notice points them to the Plugins screen so
227 * they can perform the swap themselves.
228 */
229 public function maybe_renamed_addon_notice() {
230 if ( ! current_user_can('activate_plugins') ) {
231 return;
232 }
233
234 $messages = [];
235
236 foreach ($this->renamed_addons_map() as $old_plugin => $new_plugin) {
237 $old_exists = file_exists(WP_PLUGIN_DIR . '/' . $old_plugin);
238 if ( ! $old_exists ) {
239 continue;
240 }
241
242 $messages[] = sprintf(
243 /* translators: 1: old plugin slug, 2: new plugin slug */
244 esc_html__('"%1$s" has been renamed to "%2$s". Please deactivate and remove the old version, then install the new one from the Adminify Addons screen.', 'adminify'),
245 esc_html(dirname($old_plugin)),
246 esc_html(dirname($new_plugin))
247 );
248 }
249
250 if ( empty($messages) ) {
251 return;
252 }
253
254 echo '<div class="notice notice-warning"><p><strong>' . esc_html__('Adminify', 'adminify') . ':</strong> ' . esc_html(implode('<br>', $messages)) . '</p></div>';
255 }
256
257 /**
258 * Includes
259 *
260 * @author Jewel Theme <support@jeweltheme.com>
261 */
262 public function includes()
263 {
264 // wp-load.php must never be required from within a plugin: the
265 // plugin already runs inside WordPress. The wp-admin includes
266 // below are required for plugin install/upgrade APIs used by
267 // this class and are loaded with require_once immediately
268 // before the functions from each file are called.
269 require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
270 require_once ABSPATH . 'wp-admin/includes/file.php';
271 require_once ABSPATH . 'wp-admin/includes/misc.php';
272 require_once ABSPATH . 'wp-admin/includes/plugin.php';
273 require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
274 }
275
276 /**
277 * Menu Items
278 *
279 * @author Jewel Theme <support@jeweltheme.com>
280 */
281 public function menu_items()
282 {
283 return array();
284 }
285
286 /**
287 * Plugins list
288 *
289 * @author Jewel Theme <support@jeweltheme.com>
290 */
291 public function plugins_list()
292 {
293 return array();
294 }
295
296 /**
297 * Admin submenu
298 */
299 public function admin_menu()
300 {
301 }
302
303 /**
304 * Render addons plugins body
305 */
306 public function render_addons_plugins()
307 {
308 ?>
309 <div class='wp-adminify-addons-wrapper'>
310 <?php $this->header(); ?>
311 <?php $this->body(); ?>
312 </div>
313 <?php
314 }
315
316
317 /**
318 * Addons License Header Check
319 *
320 * @return void
321 */
322
323 public function addons_check()
324 {
325 echo '<style>
326 #fs_addons .fs-cards-list{ display: flex; }
327 #fs_addons .fs-cards-list .fs-card .fs-inner .fs-cta .button{
328 top: 112px;
329 right: 12px;
330 line-height: 26px !important;
331 border-radius: 3px !important;
332 }</style>';
333 }
334
335
336
337 /**
338 * Header
339 */
340 public function header()
341 {
342 ?>
343 <div class='wp-adminify-addons-header'>
344 <div class='wp-adminify-addons-title'>
345 <h2>
346 <?php echo esc_html__('Add Ons for Adminify', 'adminify'); ?>
347 </h2>
348 <?php $this->addons_check(); ?>
349 </div>
350 <div class='wp-adminify-addons-menu'>
351 <div class="wp-filter">
352 <ul class="filter-links">
353 <?php
354 $i = 0;
355
356 foreach ($this->menu_items as $menu) {
357 $class = str_replace(' ', '-', strtolower($menu['key']));
358 ?>
359 <li class="plugin-install-<?php echo esc_attr($class); ?>">
360 <a href="#" class="<?php echo esc_attr(0 === $i ? 'current' : ''); ?>" data-type="<?php echo esc_attr($menu['key']); ?>"><?php echo esc_html($menu['label']); ?></a>
361 </li>
362 <?php
363 ++$i;
364 }
365 ?>
366 </ul>
367
368 <form class="search-form wp-adminify-search-plugins mr-0" method="get">
369 <input type="hidden" name="tab" value="search">
370 <label class="screen-reader-text" for="search-plugins">
371 <?php echo esc_html__('Search Plugins', 'adminify'); ?>
372 </label>
373 <input type="search" name="s" id="search-plugins" value="" class="wp-filter-search" placeholder="<?php echo esc_html__('Search plugins...', 'adminify'); ?>">
374 <input type="submit" id="search-submit" class="button hide-if-js" value="<?php echo esc_html__('Search Plugins', 'adminify'); ?>">
375 </form>
376 </div>
377 </div>
378 </div>
379 <?php
380 }
381
382 /**
383 * Body
384 */
385 public function body()
386 {
387 ?>
388 <div class="wp-list-table widefat plugin-install">
389 <div id="the-list">
390 <?php
391 $this->plugins();
392 ?>
393 </div>
394 </div>
395 <?php
396 }
397
398 /**
399 * Body
400 */
401 public function plugins()
402 {
403 // $this->plugins_list is populated at construction only from the
404 // cached catalogue, which is empty until a live fetch runs. The
405 // Add-ons page render is itself an explicit user action, so fall
406 // back to the bundled catalogue here so the cards always show.
407 $plugins_list = $this->plugins_list;
408
409 if ( empty( $plugins_list ) && method_exists( $this, 'get_adminify_plugins_lists' ) ) {
410 $plugins_list = (array) $this->get_adminify_plugins_lists();
411 }
412
413 foreach ($plugins_list as $key => $plugin) {
414 $install_status = \install_plugin_install_status($plugin);
415 $classes = implode(' ', $plugin['type']);
416
417 $more_details = self_admin_url(
418 'plugin-install.php?tab=plugin-information&amp;plugin=' . esc_attr($plugin['slug']) .
419 '&amp;TB_iframe=true&amp;width=600&amp;height=550'
420 );
421
422 ?>
423 <div class="plugin-card plugin-card-<?php echo esc_attr($key); ?> <?php echo esc_attr($classes); ?>">
424 <div class="plugin-card-top">
425 <div class="name column-name">
426 <h3>
427 <a href="<?php echo esc_url($more_details); ?>" class="thickbox open-plugin-details-modal">
428 <?php echo esc_html($plugin['name']); ?>
429 <img src="<?php echo esc_url($plugin['icon']); ?>" class="plugin-icon" alt="">
430 </a>
431 </h3>
432 </div>
433 <div class="desc column-description">
434 <p><?php echo wp_kses_post($plugin['short_description']); ?></p>
435 </div>
436 <!-- Hover Popup -->
437 <?php if( !empty($plugin['pricing_url']) || !empty($plugin['view_details']) ) { ?>
438 <div class="adminify-plugin-details">
439 <?php if( !empty($plugin['view_details']) ) { ?>
440 <a href="<?php echo esc_url($plugin['view_details']); ?>" target="_blank" class="adminify-view-details"><?php echo esc_html__('View Details', 'adminify'); ?></a>
441 <?php } ?>
442
443 <?php if( !empty($plugin['pricing_url']) ) { ?>
444 <a href="<?php echo esc_url($plugin['pricing_url']); ?>" target="_blank"><?php echo esc_html__('Buy Now', 'adminify'); ?></a>
445 <?php } ?>
446 </div>
447 <?php } ?>
448 </div>
449 <div class="plugin-card-bottom">
450 <div class="column-downloaded">
451 <span class="plugin-status">
452 <?php
453 echo esc_html__('Status:', 'adminify');
454
455 if ('install' === $install_status['status']) {
456 ?>
457 <span class="plugin-status-not-install" data-plugin-url="<?php echo esc_attr($plugin['download_link']); ?>"><?php echo esc_html__('No Installed', 'adminify'); ?></span>
458 <?php
459 } elseif ('update_available' === $install_status['status']) {
460 if (is_plugin_active($install_status['file'])) {
461 ?>
462 <span class="plugin-status-active">
463 <?php echo esc_html__('Active', 'adminify'); ?>
464 </span>
465 <?php
466 } else {
467 ?>
468 <span class="plugin-status-inactive" data-plugin-file="<?php echo esc_attr(esc_attr($install_status['file'])); ?>">
469 <?php echo esc_html__('Inactive', 'adminify'); ?>
470 </span>
471 <?php
472 }
473 } elseif (('latest_installed' === $install_status['status']) || ('newer_installed' === $install_status['status'])) {
474 if (is_plugin_active($install_status['file'])) {
475 ?>
476 <span class="plugin-status-active">
477 <?php echo esc_html__('Active', 'adminify'); ?>
478 </span>
479 <?php
480 } elseif (current_user_can('activate_plugin', $install_status['file'])) {
481 ?>
482 <span class="plugin-status-inactive" data-plugin-file="<?php echo esc_attr($install_status['file']); ?>">
483 <?php echo esc_html__('Inactive', 'adminify'); ?>
484 </span>
485 <?php
486 } else {
487 ?>
488 <span class="plugin-status-inactive" data-plugin-file="<?php echo esc_attr($install_status['file']); ?>">
489 <?php echo esc_html__('Inactive', 'adminify'); ?>
490 </span>
491 <?php
492 }
493 }
494 ?>
495 </span>
496 </div>
497 <div class="column-compatibility">
498 <ul class="plugin-action-buttons">
499 <?php
500 if ('install' === $install_status['status']) {
501 ?>
502 <li>
503 <button class="install-now adminify-btn adminify-btn-outline-primary" data-install-url="<?php echo esc_attr($plugin['download_link']); ?>">
504 <?php echo esc_html__('Install Now', 'adminify'); ?>
505 </button>
506 </li>
507 <?php
508 } elseif ('update_available' === $install_status['status']) {
509 ?>
510 <li class="mr-0">
511 <button class="update-now button" data-plugin="<?php echo esc_attr($install_status['file']); ?>" data-slug="<?php echo esc_attr($plugin['slug']); ?>" data-update-url="<?php echo esc_attr($install_status['url']); ?>">
512 <?php echo esc_html__('Update Now', 'adminify'); ?>
513 </button>
514 </li>
515 <?php
516 } elseif (('latest_installed' === $install_status['status']) || ('newer_installed' === $install_status['status'])) {
517 if (is_plugin_active($install_status['file'])) {
518 ?>
519 <li class="mr-0">
520 <button type="button" class="adminify-btn adminify-btn-success" disabled="disabled">
521 <?php echo esc_html__('Activated', 'adminify'); ?>
522 </button>
523 </li>
524 <?php
525 } elseif (current_user_can('activate_plugin', $install_status['file'])) {
526 ?>
527 <button class="button activate-now" data-plugin-file="<?php echo esc_attr($install_status['file']); ?>">
528 <?php echo esc_html__('Activate Now', 'adminify'); ?>
529 </button>
530 <?php
531 } else {
532 ?>
533 <li class="mr-0">
534 <button type="button" class="button button-disabled" disabled="disabled">
535 <?php echo esc_html__('Installed', 'adminify'); ?>
536 </button>
537 </li>
538 <?php
539 }
540 }
541 ?>
542 </ul>
543 </div>
544 </div>
545 </div>
546 <?php
547 }
548 }
549
550 /**
551 * Activate Plugins
552 *
553 * @author Jewel Theme <support@jeweltheme.com>
554 */
555 public function pxlbsadminify_addons_activate_plugin()
556 {
557 if (empty($_POST['plugin'])) {
558 return;
559 }
560 try {
561 $nonce = isset($_POST['nonce']) ? sanitize_text_field(wp_unslash($_POST['nonce'])) : '';
562
563 if (!wp_verify_nonce($nonce, 'pxlbsadminify_addons_nonce')) {
564 wp_send_json_error(array('mess' => __('Nonce is invalid', 'adminify')));
565 }
566
567 // Security check - only administrators can activate plugins
568 if (!current_user_can('activate_plugins')) {
569 wp_send_json_error(array('mess' => __('You do not have permission to perform this action.', 'adminify')));
570 }
571
572 $plugin = sanitize_text_field(wp_unslash($_POST['plugin']));
573 $plugin_links = array_values(wp_list_pluck($this->plugins_list, 'slug'));
574
575 if (!in_array(dirname($plugin), $plugin_links, true)) {
576 wp_send_json_error(array('mess' => __('Invalid plugin', 'adminify')));
577 }
578
579 // Resolve against the list of actually installed plugins so that
580 // only a known plugin file is ever passed to activate_plugin().
581 if (!function_exists('get_plugins')) {
582 require_once ABSPATH . 'wp-admin/includes/plugin.php';
583 }
584 $installed_plugins = array_keys(get_plugins());
585
586 if (!in_array($plugin, $installed_plugins, true)) {
587 wp_send_json_error(array('mess' => __('Invalid plugin', 'adminify')));
588 }
589
590 $result = activate_plugin($plugin);
591
592 if (is_wp_error($result)) {
593 wp_send_json_error(
594 array(
595 'mess' => $result->get_error_message(),
596 )
597 );
598 }
599 wp_send_json_success(
600 array(
601 'mess' => __('Activate success', 'adminify'),
602 )
603 );
604 } catch (\Exception $ex) {
605 wp_send_json_error(
606 array(
607 'mess' => __('Error exception.', 'adminify'),
608 array(
609 'error' => $ex,
610 ),
611 )
612 );
613 } catch (\Error $ex) {
614 wp_send_json_error(
615 array(
616 'mess' => __('Error.', 'adminify'),
617 array(
618 'error' => $ex,
619 ),
620 )
621 );
622 }
623 }
624
625 public function get_the_plugin_slug( $plugin ) {
626
627 // If the plugin is like myplugin/myplugin.php
628 if ( ! filter_var($plugin, FILTER_VALIDATE_URL) ) {
629 return dirname($plugin);
630 }
631
632 // If the plugin is from wordpress.org
633 if ( false !== strpos( $plugin, 'https://downloads.wordpress.org/plugin/' ) ) {
634 $plugin = str_replace( 'https://downloads.wordpress.org/plugin/', '', $plugin );
635 return str_replace( '.zip', '', $plugin );
636 }
637
638 // If the plugin is from local store
639 $plugin = explode( 'plugin_slug=', $plugin );
640 $plugin = explode( '&', $plugin[1] );
641 return $plugin[0];
642 }
643
644 /**
645 * Upgrade Plugins required Libraries
646 *
647 * @author Jewel Theme <support@jeweltheme.com>
648 */
649 public function pxlbsadminify_addons_upgrade_plugin( $params = null )
650 {
651 if ($params == null && empty($_POST['plugin'])) {
652 return;
653 }
654
655 try {
656 require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
657 require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
658 require_once ABSPATH . 'wp-admin/includes/class-wp-ajax-upgrader-skin.php';
659 require_once ABSPATH . 'wp-admin/includes/class-plugin-upgrader.php';
660
661 if($params == null){
662 $nonce = isset($_POST['nonce']) ? sanitize_text_field(wp_unslash($_POST['nonce'])) : '';
663
664 if (!wp_verify_nonce($nonce, 'pxlbsadminify_addons_nonce')) {
665 wp_send_json_error(array('mess' => __('Nonce is invalid', 'adminify')));
666 }
667 $plugin = sanitize_text_field(wp_unslash($_POST['plugin']));
668 }else{
669 $plugin = $params['plugin'];
670 }
671
672 // Security check - only administrators can install plugins
673 if (!current_user_can('install_plugins')) {
674 wp_send_json_error(array('mess' => __('You do not have permission to perform this action.', 'adminify')));
675 }
676
677 $plugin_slug = $this->get_the_plugin_slug( $plugin );
678
679 if ( ! array_key_exists( $plugin_slug, $this->plugins_list ) ) {
680 wp_send_json_error(array('mess' => __('Invalid plugin', 'adminify')));
681 }
682
683 // Replace the user-supplied $plugin value with values derived
684 // from our trusted internal addons list, so that arbitrary
685 // input never reaches Plugin_Upgrader::install()/upgrade() or
686 // activate_plugin().
687 $trusted_install_source = isset($this->plugins_list[$plugin_slug]['download_link'])
688 ? $this->plugins_list[$plugin_slug]['download_link']
689 : '';
690
691 if($params == null){
692 $type = isset($_POST['type']) ? sanitize_text_field(wp_unslash($_POST['type'])) : 'install';
693 }else{
694 $type = 'install';
695 }
696 $skin = new \WP_Ajax_Upgrader_Skin();
697 $upgrader = new \Plugin_Upgrader($skin);
698
699 if ('install' === $type) {
700
701 if ( empty( $trusted_install_source ) ) {
702 wp_send_json_error(array('mess' => __('Invalid plugin', 'adminify')));
703 }
704
705 $result = $upgrader->install( $trusted_install_source );
706 if ($params == null){
707 if (empty($result) || empty($upgrader->result)) {
708 wp_send_json_error(
709 array(
710 'mess' => 'Something is wrong',
711 )
712 );
713 }
714
715 if (is_wp_error($result)) {
716 wp_send_json_error(
717 array(
718 'mess' => $result->get_error_message(),
719 )
720 );
721 }
722 }else{
723 if(empty($result) || empty($upgrader->result)){
724 return;
725 }
726 }
727
728 $plugins = get_plugins('/' . $upgrader->result['destination_name']);
729 $plugin_data = end($plugins);
730 $plugin_data['slug'] = $upgrader->result['destination_name'];
731 $plugin_data['version'] = $plugin_data['Version'];
732
733 if (!empty($plugin_data) && !is_wp_error($plugin_data)) {
734
735 $install_status = \install_plugin_install_status($plugin_data);
736
737 $active_plugin = activate_plugin($install_status['file']);
738
739 if ($params == null){
740 if (is_wp_error($active_plugin)) {
741 wp_send_json_error(
742 array(
743 'mess' => $active_plugin->get_error_message(),
744 )
745 );
746 } else {
747 wp_send_json_success(
748 array(
749 'mess' => __('Install success', 'adminify'),
750 )
751 );
752 }
753 }
754 } else {
755 if ($params == null){
756 wp_send_json_error(
757 array(
758 'mess' => 'Error',
759 )
760 );
761
762 }
763 }
764 } else {
765
766 // Resolve the trusted plugin file path from the validated
767 // slug instead of trusting the raw $_POST value, so that
768 // is_plugin_active(), Plugin_Upgrader::upgrade() and
769 // activate_plugin() never receive attacker-supplied paths.
770 $installed_plugins = get_plugins( '/' . $plugin_slug );
771 if ( empty( $installed_plugins ) ) {
772 wp_send_json_error(array('mess' => __('Plugin not installed.', 'adminify')));
773 }
774 $trusted_plugin_file = $plugin_slug . '/' . key( $installed_plugins );
775
776 $is_active = is_plugin_active( $trusted_plugin_file );
777 $result = $upgrader->upgrade( $trusted_plugin_file );
778
779 if ($params == null){
780 if ( empty($result) || is_wp_error($result) ) {
781 wp_send_json_error(
782 array(
783 'mess' => is_wp_error($result) ? $result->get_error_message() : __('Couldn\'t upgrade', 'adminify')
784 )
785 );
786 }
787 }
788
789 $active_status = activate_plugin( $trusted_plugin_file );
790
791 if ($params == null){
792 if ( empty($active_status) || is_wp_error($active_status) ) {
793 wp_send_json_error(
794 array(
795 'mess' => is_wp_error($result) ? $result->get_error_message() : __('Activation Failed', 'adminify')
796 )
797 );
798 }
799
800 wp_send_json_success(
801 array(
802 'mess' => __('Update success', 'adminify'),
803 'active' => true,
804 )
805 );
806 }
807 }
808
809 } catch (\Exception $ex) {
810 if ($params == null){
811 wp_send_json_error(
812 array(
813 'mess' => __('Error exception.', 'adminify'),
814 array(
815 'error' => $ex,
816 ),
817 )
818 );
819 }
820 }
821 }
822
823 }
824 }
825