| [ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Plugins administration panel. 4 * 5 * @package WordPress 6 * @subpackage Administration 7 */ 8 9 /** WordPress Administration Bootstrap */ 10 require_once __DIR__ . '/admin.php'; 11 12 /** 13 * @global string $status Current plugin status view, set by WP_Plugins_List_Table. 14 * @global int $page Current page number, set by WP_Plugins_List_Table. 15 * @global array $plugins Set by WP_Plugins_List_Table::prepare_items(). 16 * @global int $user_ID ID of the current user, set during authentication. 17 */ 18 global $status, $page, $plugins, $user_ID; 19 20 if ( ! current_user_can( 'activate_plugins' ) ) { 21 wp_die( __( 'Sorry, you are not allowed to manage plugins for this site.' ) ); 22 } 23 24 $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' ); 25 $pagenum = $wp_list_table->get_pagenum(); 26 27 $action = $wp_list_table->current_action(); 28 29 $plugin = isset( $_REQUEST['plugin'] ) ? wp_unslash( $_REQUEST['plugin'] ) : ''; 30 $s = isset( $_REQUEST['s'] ) ? urlencode( wp_unslash( $_REQUEST['s'] ) ) : ''; 31 32 // Clean up request URI from temporary args for screen options/paging uri's to work as expected. 33 $query_args_to_remove = array( 34 'error', 35 'deleted', 36 'activate', 37 'activate-multi', 38 'deactivate', 39 'deactivate-multi', 40 'enabled-auto-update', 41 'disabled-auto-update', 42 'enabled-auto-update-multi', 43 'disabled-auto-update-multi', 44 '_error_nonce', 45 ); 46 47 $_SERVER['REQUEST_URI'] = remove_query_arg( $query_args_to_remove, $_SERVER['REQUEST_URI'] ); 48 49 wp_enqueue_script( 'updates' ); 50 51 WP_Plugin_Dependencies::initialize(); 52 53 if ( $action ) { 54 55 switch ( $action ) { 56 case 'activate': 57 if ( ! current_user_can( 'activate_plugin', $plugin ) ) { 58 wp_die( __( 'Sorry, you are not allowed to activate this plugin.' ) ); 59 } 60 61 if ( is_multisite() && ! is_network_admin() && is_network_only_plugin( $plugin ) ) { 62 wp_redirect( self_admin_url( "plugins.php?plugin_status=$status&paged=$page&s=$s" ) ); 63 exit; 64 } 65 66 check_admin_referer( 'activate-plugin_' . $plugin ); 67 68 $result = activate_plugin( $plugin, self_admin_url( 'plugins.php?error=true&plugin=' . urlencode( $plugin ) ), is_network_admin() ); 69 if ( is_wp_error( $result ) ) { 70 if ( 'unexpected_output' === $result->get_error_code() ) { 71 $redirect = self_admin_url( 'plugins.php?error=true&charsout=' . strlen( $result->get_error_data() ) . '&plugin=' . urlencode( $plugin ) . "&plugin_status=$status&paged=$page&s=$s" ); 72 wp_redirect( add_query_arg( '_error_nonce', wp_create_nonce( 'plugin-activation-error_' . $plugin ), $redirect ) ); 73 exit; 74 } else { 75 wp_die( $result ); 76 } 77 } 78 79 if ( ! is_network_admin() ) { 80 $recent = (array) get_option( 'recently_activated' ); 81 unset( $recent[ $plugin ] ); 82 update_option( 'recently_activated', $recent, false ); 83 } else { 84 $recent = (array) get_site_option( 'recently_activated' ); 85 unset( $recent[ $plugin ] ); 86 update_site_option( 'recently_activated', $recent ); 87 } 88 89 if ( isset( $_GET['from'] ) && 'import' === $_GET['from'] ) { 90 // Overrides the ?error=true one above and redirects to the Imports page, stripping the -importer suffix. 91 wp_redirect( self_admin_url( 'import.php?import=' . str_replace( '-importer', '', dirname( $plugin ) ) ) ); 92 } elseif ( isset( $_GET['from'] ) && 'press-this' === $_GET['from'] ) { 93 wp_redirect( self_admin_url( 'press-this.php' ) ); 94 } else { 95 // Overrides the ?error=true one above. 96 wp_redirect( self_admin_url( "plugins.php?activate=true&plugin_status=$status&paged=$page&s=$s" ) ); 97 } 98 exit; 99 100 case 'activate-selected': 101 if ( ! current_user_can( 'activate_plugins' ) ) { 102 wp_die( __( 'Sorry, you are not allowed to activate plugins for this site.' ) ); 103 } 104 105 check_admin_referer( 'bulk-plugins' ); 106 107 $plugins = isset( $_POST['checked'] ) ? (array) wp_unslash( $_POST['checked'] ) : array(); 108 109 if ( is_network_admin() ) { 110 foreach ( $plugins as $i => $plugin ) { 111 // Only activate plugins which are not already network activated. 112 if ( is_plugin_active_for_network( $plugin ) ) { 113 unset( $plugins[ $i ] ); 114 } 115 } 116 } else { 117 foreach ( $plugins as $i => $plugin ) { 118 // Only activate plugins which are not already active and are not network-only when on Multisite. 119 if ( is_plugin_active( $plugin ) || ( is_multisite() && is_network_only_plugin( $plugin ) ) ) { 120 unset( $plugins[ $i ] ); 121 } 122 // Only activate plugins which the user can activate. 123 if ( ! current_user_can( 'activate_plugin', $plugin ) ) { 124 unset( $plugins[ $i ] ); 125 } 126 } 127 } 128 129 if ( empty( $plugins ) ) { 130 wp_redirect( self_admin_url( "plugins.php?plugin_status=$status&paged=$page&s=$s" ) ); 131 exit; 132 } 133 134 activate_plugins( $plugins, self_admin_url( 'plugins.php?error=true' ), is_network_admin() ); 135 136 if ( ! is_network_admin() ) { 137 $recent = (array) get_option( 'recently_activated' ); 138 } else { 139 $recent = (array) get_site_option( 'recently_activated' ); 140 } 141 142 foreach ( $plugins as $plugin ) { 143 unset( $recent[ $plugin ] ); 144 } 145 146 if ( ! is_network_admin() ) { 147 update_option( 'recently_activated', $recent, false ); 148 } else { 149 update_site_option( 'recently_activated', $recent ); 150 } 151 152 wp_redirect( self_admin_url( "plugins.php?activate-multi=true&plugin_status=$status&paged=$page&s=$s" ) ); 153 exit; 154 155 case 'update-selected': 156 check_admin_referer( 'bulk-plugins' ); 157 158 if ( isset( $_GET['plugins'] ) ) { 159 $plugins = explode( ',', wp_unslash( $_GET['plugins'] ) ); 160 } elseif ( isset( $_POST['checked'] ) ) { 161 $plugins = (array) wp_unslash( $_POST['checked'] ); 162 } else { 163 $plugins = array(); 164 } 165 166 // Used in the HTML title tag. 167 $title = __( 'Update Plugins' ); 168 $parent_file = 'plugins.php'; 169 170 wp_enqueue_script( 'updates' ); 171 require_once ABSPATH . 'wp-admin/admin-header.php'; 172 173 echo '<div class="wrap">'; 174 echo '<h1>' . esc_html( $title ) . '</h1>'; 175 176 $url = self_admin_url( 'update.php?action=update-selected&plugins=' . urlencode( implode( ',', $plugins ) ) ); 177 $url = wp_nonce_url( $url, 'bulk-update-plugins' ); 178 179 echo "<iframe src='$url' style='width: 100%; height:100%; min-height:850px;'></iframe>"; 180 echo '</div>'; 181 require_once ABSPATH . 'wp-admin/admin-footer.php'; 182 exit; 183 184 case 'error_scrape': 185 if ( ! current_user_can( 'activate_plugin', $plugin ) ) { 186 wp_die( __( 'Sorry, you are not allowed to activate this plugin.' ) ); 187 } 188 189 check_admin_referer( 'plugin-activation-error_' . $plugin ); 190 191 $valid = validate_plugin( $plugin ); 192 if ( is_wp_error( $valid ) ) { 193 wp_die( $valid ); 194 } 195 196 if ( ! WP_DEBUG ) { 197 error_reporting( E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING | E_RECOVERABLE_ERROR ); 198 } 199 200 ini_set( 'display_errors', true ); // Ensure that fatal errors are displayed. 201 // Go back to "sandbox" scope so we get the same errors as before. 202 plugin_sandbox_scrape( $plugin ); 203 /** This action is documented in wp-admin/includes/plugin.php */ 204 do_action( "activate_{$plugin}", is_network_admin() ); 205 exit; 206 207 case 'deactivate': 208 if ( ! current_user_can( 'deactivate_plugin', $plugin ) ) { 209 wp_die( __( 'Sorry, you are not allowed to deactivate this plugin.' ) ); 210 } 211 212 check_admin_referer( 'deactivate-plugin_' . $plugin ); 213 214 if ( ! is_network_admin() && is_plugin_active_for_network( $plugin ) ) { 215 wp_redirect( self_admin_url( "plugins.php?plugin_status=$status&paged=$page&s=$s" ) ); 216 exit; 217 } 218 219 deactivate_plugins( $plugin, false, is_network_admin() ); 220 221 if ( ! is_network_admin() ) { 222 update_option( 'recently_activated', array( $plugin => time() ) + (array) get_option( 'recently_activated' ), false ); 223 } else { 224 update_site_option( 'recently_activated', array( $plugin => time() ) + (array) get_site_option( 'recently_activated' ) ); 225 } 226 227 if ( headers_sent() ) { 228 echo "<meta http-equiv='refresh' content='" . esc_attr( "0;url=plugins.php?deactivate=true&plugin_status=$status&paged=$page&s=$s" ) . "' />"; 229 } else { 230 wp_redirect( self_admin_url( "plugins.php?deactivate=true&plugin_status=$status&paged=$page&s=$s" ) ); 231 } 232 exit; 233 234 case 'deactivate-selected': 235 if ( ! current_user_can( 'deactivate_plugins' ) ) { 236 wp_die( __( 'Sorry, you are not allowed to deactivate plugins for this site.' ) ); 237 } 238 239 check_admin_referer( 'bulk-plugins' ); 240 241 $plugins = isset( $_POST['checked'] ) ? (array) wp_unslash( $_POST['checked'] ) : array(); 242 // Do not deactivate plugins which are already deactivated. 243 if ( is_network_admin() ) { 244 $plugins = array_filter( $plugins, 'is_plugin_active_for_network' ); 245 } else { 246 $plugins = array_filter( $plugins, 'is_plugin_active' ); 247 $plugins = array_diff( $plugins, array_filter( $plugins, 'is_plugin_active_for_network' ) ); 248 249 foreach ( $plugins as $i => $plugin ) { 250 // Only deactivate plugins which the user can deactivate. 251 if ( ! current_user_can( 'deactivate_plugin', $plugin ) ) { 252 unset( $plugins[ $i ] ); 253 } 254 } 255 } 256 if ( empty( $plugins ) ) { 257 wp_redirect( self_admin_url( "plugins.php?plugin_status=$status&paged=$page&s=$s" ) ); 258 exit; 259 } 260 261 deactivate_plugins( $plugins, false, is_network_admin() ); 262 263 $deactivated = array(); 264 foreach ( $plugins as $plugin ) { 265 $deactivated[ $plugin ] = time(); 266 } 267 268 if ( ! is_network_admin() ) { 269 update_option( 'recently_activated', $deactivated + (array) get_option( 'recently_activated' ), false ); 270 } else { 271 update_site_option( 'recently_activated', $deactivated + (array) get_site_option( 'recently_activated' ) ); 272 } 273 274 wp_redirect( self_admin_url( "plugins.php?deactivate-multi=true&plugin_status=$status&paged=$page&s=$s" ) ); 275 exit; 276 277 case 'delete-selected': 278 if ( ! current_user_can( 'delete_plugins' ) ) { 279 wp_die( __( 'Sorry, you are not allowed to delete plugins for this site.' ) ); 280 } 281 282 check_admin_referer( 'bulk-plugins' ); 283 284 // $_POST = from the plugin form; $_GET = from the FTP details screen. 285 $plugins = isset( $_REQUEST['checked'] ) ? (array) wp_unslash( $_REQUEST['checked'] ) : array(); 286 if ( empty( $plugins ) ) { 287 wp_redirect( self_admin_url( "plugins.php?plugin_status=$status&paged=$page&s=$s" ) ); 288 exit; 289 } 290 291 $plugins = array_filter( $plugins, 'is_plugin_inactive' ); // Do not allow to delete activated plugins. 292 if ( empty( $plugins ) ) { 293 wp_redirect( self_admin_url( "plugins.php?error=true&main=true&plugin_status=$status&paged=$page&s=$s" ) ); 294 exit; 295 } 296 297 // Bail on all if any paths are invalid. 298 // validate_file() returns truthy for invalid files. 299 $invalid_plugin_files = array_filter( $plugins, 'validate_file' ); 300 if ( $invalid_plugin_files ) { 301 wp_redirect( self_admin_url( "plugins.php?plugin_status=$status&paged=$page&s=$s" ) ); 302 exit; 303 } 304 305 require ABSPATH . 'wp-admin/update.php'; 306 307 $parent_file = 'plugins.php'; 308 309 if ( ! isset( $_REQUEST['verify-delete'] ) ) { 310 wp_enqueue_script( 'jquery' ); 311 require_once ABSPATH . 'wp-admin/admin-header.php'; 312 313 ?> 314 <div class="wrap"> 315 <?php 316 317 $plugin_info = array(); 318 $have_non_network_plugins = false; 319 320 foreach ( (array) $plugins as $plugin ) { 321 $plugin_slug = dirname( $plugin ); 322 323 if ( '.' === $plugin_slug ) { 324 $data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin ); 325 if ( $data ) { 326 $plugin_info[ $plugin ] = $data; 327 $plugin_info[ $plugin ]['is_uninstallable'] = is_uninstallable_plugin( $plugin ); 328 if ( ! $plugin_info[ $plugin ]['Network'] ) { 329 $have_non_network_plugins = true; 330 } 331 } 332 } else { 333 // Get plugins list from that folder. 334 $folder_plugins = get_plugins( '/' . $plugin_slug ); 335 if ( $folder_plugins ) { 336 foreach ( $folder_plugins as $plugin_file => $data ) { 337 $plugin_info[ $plugin_file ] = _get_plugin_data_markup_translate( $plugin_file, $data ); 338 $plugin_info[ $plugin_file ]['is_uninstallable'] = is_uninstallable_plugin( $plugin ); 339 if ( ! $plugin_info[ $plugin_file ]['Network'] ) { 340 $have_non_network_plugins = true; 341 } 342 } 343 } 344 } 345 } 346 347 $plugins_to_delete = count( $plugin_info ); 348 349 ?> 350 <?php if ( 1 === $plugins_to_delete ) : ?> 351 <h1><?php _e( 'Delete Plugin' ); ?></h1> 352 <?php 353 if ( $have_non_network_plugins && is_network_admin() ) : 354 $maybe_active_plugin = '<strong>' . __( 'Caution:' ) . '</strong> ' . __( 'This plugin may be active on other sites in the network.' ); 355 wp_admin_notice( 356 $maybe_active_plugin, 357 array( 358 'additional_classes' => array( 'error' ), 359 ) 360 ); 361 endif; 362 ?> 363 <p><?php _e( 'You are about to remove the following plugin:' ); ?></p> 364 <?php else : ?> 365 <h1><?php _e( 'Delete Plugins' ); ?></h1> 366 <?php 367 if ( $have_non_network_plugins && is_network_admin() ) : 368 $maybe_active_plugins = '<strong>' . __( 'Caution:' ) . '</strong> ' . __( 'These plugins may be active on other sites in the network.' ); 369 wp_admin_notice( 370 $maybe_active_plugins, 371 array( 372 'additional_classes' => array( 'error' ), 373 ) 374 ); 375 endif; 376 ?> 377 <p><?php _e( 'You are about to remove the following plugins:' ); ?></p> 378 <?php endif; ?> 379 <ul class="ul-disc"> 380 <?php 381 382 $data_to_delete = false; 383 384 foreach ( $plugin_info as $plugin ) { 385 if ( $plugin['is_uninstallable'] ) { 386 /* translators: 1: Plugin name, 2: Plugin author. */ 387 echo '<li>', sprintf( __( '%1$s by %2$s (will also <strong>delete its data</strong>)' ), '<strong>' . $plugin['Name'] . '</strong>', '<em>' . $plugin['AuthorName'] . '</em>' ), '</li>'; 388 $data_to_delete = true; 389 } else { 390 /* translators: 1: Plugin name, 2: Plugin author. */ 391 echo '<li>', sprintf( _x( '%1$s by %2$s', 'plugin' ), '<strong>' . $plugin['Name'] . '</strong>', '<em>' . $plugin['AuthorName'] ) . '</em>', '</li>'; 392 } 393 } 394 395 ?> 396 </ul> 397 <p> 398 <?php 399 400 if ( $data_to_delete ) { 401 _e( 'Are you sure you want to delete these files and data?' ); 402 } else { 403 _e( 'Are you sure you want to delete these files?' ); 404 } 405 406 ?> 407 </p> 408 <form method="post" action="<?php echo esc_url( $_SERVER['REQUEST_URI'] ); ?>" style="display:inline;"> 409 <input type="hidden" name="verify-delete" value="1" /> 410 <input type="hidden" name="action" value="delete-selected" /> 411 <?php 412 413 foreach ( (array) $plugins as $plugin ) { 414 echo '<input type="hidden" name="checked[]" value="' . esc_attr( $plugin ) . '" />'; 415 } 416 417 ?> 418 <?php wp_nonce_field( 'bulk-plugins' ); ?> 419 <?php submit_button( $data_to_delete ? __( 'Yes, delete these files and data' ) : __( 'Yes, delete these files' ), '', 'submit', false ); ?> 420 </form> 421 <?php 422 423 $referer = wp_get_referer(); 424 425 ?> 426 <form method="post" action="<?php echo $referer ? esc_url( $referer ) : ''; ?>" style="display:inline;"> 427 <?php submit_button( __( 'No, return me to the plugin list' ), '', 'submit', false ); ?> 428 </form> 429 </div> 430 <?php 431 432 require_once ABSPATH . 'wp-admin/admin-footer.php'; 433 exit; 434 } else { 435 $plugins_to_delete = count( $plugins ); 436 } // End if verify-delete. 437 438 $delete_result = delete_plugins( $plugins ); 439 440 // Store the result in an option rather than a URL param due to object type & length. 441 // Cannot use transient/cache, as that could get flushed if any plugin flushes data on uninstall/delete. 442 update_option( 'plugins_delete_result_' . $user_ID, $delete_result, false ); 443 wp_redirect( self_admin_url( "plugins.php?deleted=$plugins_to_delete&plugin_status=$status&paged=$page&s=$s" ) ); 444 exit; 445 case 'clear-recent-list': 446 if ( ! is_network_admin() ) { 447 update_option( 'recently_activated', array(), false ); 448 } else { 449 update_site_option( 'recently_activated', array() ); 450 } 451 452 break; 453 case 'resume': 454 if ( is_multisite() ) { 455 return; 456 } 457 458 if ( ! current_user_can( 'resume_plugin', $plugin ) ) { 459 wp_die( __( 'Sorry, you are not allowed to resume this plugin.' ) ); 460 } 461 462 check_admin_referer( 'resume-plugin_' . $plugin ); 463 464 $result = resume_plugin( $plugin, self_admin_url( "plugins.php?error=resuming&plugin_status=$status&paged=$page&s=$s" ) ); 465 466 if ( is_wp_error( $result ) ) { 467 wp_die( $result ); 468 } 469 470 wp_redirect( self_admin_url( "plugins.php?resume=true&plugin_status=$status&paged=$page&s=$s" ) ); 471 exit; 472 case 'enable-auto-update': 473 case 'disable-auto-update': 474 case 'enable-auto-update-selected': 475 case 'disable-auto-update-selected': 476 if ( ! current_user_can( 'update_plugins' ) || ! wp_is_auto_update_enabled_for_type( 'plugin' ) ) { 477 wp_die( __( 'Sorry, you are not allowed to manage plugins automatic updates.' ) ); 478 } 479 480 if ( is_multisite() && ! is_network_admin() ) { 481 wp_die( __( 'Please connect to your network admin to manage plugins automatic updates.' ) ); 482 } 483 484 $redirect = self_admin_url( "plugins.php?plugin_status={$status}&paged={$page}&s={$s}" ); 485 486 if ( 'enable-auto-update' === $action || 'disable-auto-update' === $action ) { 487 if ( empty( $plugin ) ) { 488 wp_redirect( $redirect ); 489 exit; 490 } 491 492 check_admin_referer( 'updates' ); 493 } else { 494 if ( empty( $_POST['checked'] ) ) { 495 wp_redirect( $redirect ); 496 exit; 497 } 498 499 check_admin_referer( 'bulk-plugins' ); 500 } 501 502 $auto_updates = (array) get_site_option( 'auto_update_plugins', array() ); 503 504 if ( 'enable-auto-update' === $action ) { 505 $auto_updates[] = $plugin; 506 $auto_updates = array_unique( $auto_updates ); 507 $redirect = add_query_arg( array( 'enabled-auto-update' => 'true' ), $redirect ); 508 } elseif ( 'disable-auto-update' === $action ) { 509 $auto_updates = array_diff( $auto_updates, array( $plugin ) ); 510 $redirect = add_query_arg( array( 'disabled-auto-update' => 'true' ), $redirect ); 511 } else { 512 $plugins = (array) wp_unslash( $_POST['checked'] ); 513 514 if ( 'enable-auto-update-selected' === $action ) { 515 $new_auto_updates = array_merge( $auto_updates, $plugins ); 516 $new_auto_updates = array_unique( $new_auto_updates ); 517 $query_args = array( 'enabled-auto-update-multi' => 'true' ); 518 } else { 519 $new_auto_updates = array_diff( $auto_updates, $plugins ); 520 $query_args = array( 'disabled-auto-update-multi' => 'true' ); 521 } 522 523 // Return early if all selected plugins already have auto-updates enabled or disabled. 524 // Must use non-strict comparison, so that array order is not treated as significant. 525 if ( $new_auto_updates == $auto_updates ) { // phpcs:ignore Universal.Operators.StrictComparisons.LooseEqual 526 wp_redirect( $redirect ); 527 exit; 528 } 529 530 $auto_updates = $new_auto_updates; 531 $redirect = add_query_arg( $query_args, $redirect ); 532 } 533 534 /** This filter is documented in wp-admin/includes/class-wp-plugins-list-table.php */ 535 $all_items = apply_filters( 'all_plugins', get_plugins() ); 536 537 // Remove plugins that don't exist or have been deleted since the option was last updated. 538 $auto_updates = array_intersect( $auto_updates, array_keys( $all_items ) ); 539 540 update_site_option( 'auto_update_plugins', $auto_updates ); 541 542 wp_redirect( $redirect ); 543 exit; 544 default: 545 if ( isset( $_POST['checked'] ) ) { 546 check_admin_referer( 'bulk-plugins' ); 547 548 $screen = get_current_screen()->id; 549 $sendback = wp_get_referer(); 550 $plugins = isset( $_POST['checked'] ) ? (array) wp_unslash( $_POST['checked'] ) : array(); 551 552 /** This action is documented in wp-admin/edit.php */ 553 $sendback = apply_filters( "handle_bulk_actions-{$screen}", $sendback, $action, $plugins ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores 554 wp_safe_redirect( $sendback ); 555 exit; 556 } 557 break; 558 } 559 } 560 561 $wp_list_table->prepare_items(); 562 563 wp_enqueue_script( 'plugin-install' ); 564 add_thickbox(); 565 566 add_screen_option( 'per_page', array( 'default' => 999 ) ); 567 568 get_current_screen()->add_help_tab( 569 array( 570 'id' => 'overview', 571 'title' => __( 'Overview' ), 572 'content' => 573 '<p>' . __( 'Plugins extend and expand the functionality of WordPress. Once a plugin is installed, you may activate it or deactivate it here.' ) . '</p>' . 574 '<p>' . __( 'The search for installed plugins will search for terms in their name, description, or author.' ) . ' <span id="live-search-desc" class="hide-if-no-js">' . __( 'The search results will be updated as you type.' ) . '</span></p>' . 575 '<p>' . sprintf( 576 /* translators: %s: WordPress Plugin Directory URL. */ 577 __( 'If you would like to see more plugins to choose from, click on the “Add Plugin” button and you will be able to browse or search for additional plugins from the <a href="%s">WordPress Plugin Directory</a>. Plugins in the WordPress Plugin Directory are designed and developed by third parties, and are compatible with the license WordPress uses. Oh, and they are free!' ), 578 __( 'https://wordpress.org/plugins/' ) 579 ) . '</p>', 580 ) 581 ); 582 get_current_screen()->add_help_tab( 583 array( 584 'id' => 'compatibility-problems', 585 'title' => __( 'Troubleshooting' ), 586 'content' => 587 '<p>' . __( 'Most of the time, plugins play nicely with the core of WordPress and with other plugins. Sometimes, though, a plugin’s code will get in the way of another plugin, causing compatibility issues. If your site starts doing strange things, this may be the problem. Try deactivating all your plugins and re-activating them in various combinations until you isolate which one(s) caused the issue.' ) . '</p>' . 588 '<p>' . sprintf( 589 /* translators: %s: WP_PLUGIN_DIR constant value. */ 590 __( 'If something goes wrong with a plugin and you cannot use WordPress, delete or rename that file in the %s directory and it will be automatically deactivated.' ), 591 '<code>' . WP_PLUGIN_DIR . '</code>' 592 ) . '</p>', 593 ) 594 ); 595 596 $help_sidebar_autoupdates = ''; 597 598 if ( current_user_can( 'update_plugins' ) && wp_is_auto_update_enabled_for_type( 'plugin' ) ) { 599 get_current_screen()->add_help_tab( 600 array( 601 'id' => 'plugins-themes-auto-updates', 602 'title' => __( 'Auto-updates' ), 603 'content' => 604 '<p>' . __( 'Auto-updates can be enabled or disabled for each individual plugin. Plugins with auto-updates enabled will display the estimated date of the next auto-update. Auto-updates depends on the WP-Cron task scheduling system.' ) . '</p>' . 605 '<p>' . __( 'Auto-updates are only available for plugins recognized by WordPress.org, or that include a compatible update system.' ) . '</p>' . 606 '<p>' . __( 'Please note: Third-party themes and plugins, or custom code, may override WordPress scheduling.' ) . '</p>', 607 ) 608 ); 609 610 $help_sidebar_autoupdates = '<p>' . __( '<a href="https://wordpress.org/documentation/article/plugins-themes-auto-updates/">Documentation on Auto-updates</a>' ) . '</p>'; 611 } 612 613 if ( current_user_can( 'install_plugins' ) ) { 614 get_current_screen()->add_help_tab( 615 array( 616 'id' => 'plugins-dependencies', 617 'title' => __( 'Dependencies' ), 618 'content' => 619 '<p>' . __( 'Plugin Dependencies aims to make the process of installing and activating add-ons (dependents) and the plugins they rely on (dependencies) consistent and easy.' ) . '</p>' . 620 '<p>' . __( 'If a required plugin is deleted, a notice will be displayed on the Plugin administration screen informing the user that there is some missing dependencies to install and/or activate. Additionally, each plugin whose dependencies are not met will have an error notice on their plugin row.' ) . '</p>' . 621 '<p>' . __( 'If a dependent plugin is missing some dependencies, its activation button will be disabled until the required dependencies are activated.' ) . '</p>', 622 ) 623 ); 624 } 625 626 get_current_screen()->set_help_sidebar( 627 '<p><strong>' . __( 'For more information:' ) . '</strong></p>' . 628 '<p>' . __( '<a href="https://wordpress.org/documentation/article/manage-plugins/">Documentation on Managing Plugins</a>' ) . '</p>' . 629 $help_sidebar_autoupdates . 630 '<p>' . __( '<a href="https://wordpress.org/support/forums/">Support forums</a>' ) . '</p>' 631 ); 632 633 get_current_screen()->set_screen_reader_content( 634 array( 635 'heading_views' => __( 'Filter plugins list' ), 636 'heading_pagination' => __( 'Plugins list navigation' ), 637 'heading_list' => __( 'Plugins list' ), 638 ) 639 ); 640 641 // Used in the HTML title tag. 642 $title = __( 'Plugins' ); 643 $parent_file = 'plugins.php'; 644 645 require_once ABSPATH . 'wp-admin/admin-header.php'; 646 647 $invalid = validate_active_plugins(); 648 if ( ! empty( $invalid ) ) { 649 foreach ( $invalid as $plugin_file => $error ) { 650 $deactivated_message = sprintf( 651 /* translators: 1: Plugin file, 2: Error message. */ 652 __( 'The plugin %1$s has been deactivated due to an error: %2$s' ), 653 '<code>' . esc_html( $plugin_file ) . '</code>', 654 esc_html( $error->get_error_message() ) 655 ); 656 wp_admin_notice( 657 $deactivated_message, 658 array( 659 'id' => 'message', 660 'additional_classes' => array( 'error' ), 661 ) 662 ); 663 } 664 } 665 666 // Used by wp_admin_notice() updated notices. 667 $updated_notice_args = array( 668 'id' => 'message', 669 'additional_classes' => array( 'updated' ), 670 'dismissible' => true, 671 ); 672 if ( isset( $_GET['error'] ) ) { 673 674 if ( isset( $_GET['main'] ) ) { 675 $errmsg = __( 'You cannot delete a plugin while it is active on the main site.' ); 676 } elseif ( isset( $_GET['charsout'] ) ) { 677 $errmsg = sprintf( 678 /* translators: %d: Number of characters. */ 679 _n( 680 'The plugin generated %d character of <strong>unexpected output</strong> during activation.', 681 'The plugin generated %d characters of <strong>unexpected output</strong> during activation.', 682 $_GET['charsout'] 683 ), 684 $_GET['charsout'] 685 ); 686 $errmsg .= ' ' . __( 'If you notice “headers already sent” messages, problems with syndication feeds or other issues, try deactivating or removing this plugin.' ); 687 } elseif ( 'resuming' === $_GET['error'] ) { 688 $errmsg = __( 'Plugin could not be resumed because it triggered a <strong>fatal error</strong>.' ); 689 } else { 690 $errmsg = __( 'Plugin could not be activated because it triggered a <strong>fatal error</strong>.' ); 691 } 692 693 if ( ! isset( $_GET['main'] ) && ! isset( $_GET['charsout'] ) 694 && isset( $_GET['_error_nonce'] ) && wp_verify_nonce( $_GET['_error_nonce'], 'plugin-activation-error_' . $plugin ) 695 ) { 696 $iframe_url = add_query_arg( 697 array( 698 'action' => 'error_scrape', 699 'plugin' => urlencode( $plugin ), 700 '_wpnonce' => urlencode( $_GET['_error_nonce'] ), 701 ), 702 admin_url( 'plugins.php' ) 703 ); 704 705 $errmsg .= '<iframe style="border:0" width="100%" height="70px" src="' . esc_url( $iframe_url ) . '"></iframe>'; 706 } 707 708 wp_admin_notice( 709 $errmsg, 710 array( 711 'id' => 'message', 712 'additional_classes' => array( 'error' ), 713 ) 714 ); 715 716 } elseif ( isset( $_GET['deleted'] ) ) { 717 $delete_result = get_option( 'plugins_delete_result_' . $user_ID ); 718 // Delete it once we're done. 719 delete_option( 'plugins_delete_result_' . $user_ID ); 720 721 if ( is_wp_error( $delete_result ) ) { 722 $plugin_not_deleted_message = sprintf( 723 /* translators: %s: Error message. */ 724 __( 'Plugin could not be deleted due to an error: %s' ), 725 esc_html( $delete_result->get_error_message() ) 726 ); 727 wp_admin_notice( 728 $plugin_not_deleted_message, 729 array( 730 'id' => 'message', 731 'additional_classes' => array( 'error' ), 732 'dismissible' => true, 733 ) 734 ); 735 } else { 736 if ( 1 === (int) $_GET['deleted'] ) { 737 $plugins_deleted_message = __( 'The selected plugin has been deleted.' ); 738 } else { 739 $plugins_deleted_message = __( 'The selected plugins have been deleted.' ); 740 } 741 wp_admin_notice( $plugins_deleted_message, $updated_notice_args ); 742 } 743 } elseif ( isset( $_GET['activate'] ) ) { 744 wp_admin_notice( __( 'Plugin activated.' ), $updated_notice_args ); 745 } elseif ( isset( $_GET['activate-multi'] ) ) { 746 wp_admin_notice( __( 'Selected plugins activated.' ), $updated_notice_args ); 747 } elseif ( isset( $_GET['deactivate'] ) ) { 748 wp_admin_notice( __( 'Plugin deactivated.' ), $updated_notice_args ); 749 } elseif ( isset( $_GET['deactivate-multi'] ) ) { 750 wp_admin_notice( __( 'Selected plugins deactivated.' ), $updated_notice_args ); 751 } elseif ( isset( $_GET['resume'] ) ) { 752 wp_admin_notice( __( 'Plugin resumed.' ), $updated_notice_args ); 753 } elseif ( isset( $_GET['enabled-auto-update'] ) ) { 754 wp_admin_notice( __( 'Plugin will be auto-updated.' ), $updated_notice_args ); 755 } elseif ( isset( $_GET['disabled-auto-update'] ) ) { 756 wp_admin_notice( __( 'Plugin will no longer be auto-updated.' ), $updated_notice_args ); 757 } elseif ( isset( $_GET['enabled-auto-update-multi'] ) ) { 758 wp_admin_notice( __( 'Selected plugins will be auto-updated.' ), $updated_notice_args ); 759 } elseif ( isset( $_GET['disabled-auto-update-multi'] ) ) { 760 wp_admin_notice( __( 'Selected plugins will no longer be auto-updated.' ), $updated_notice_args ); 761 } 762 ?> 763 764 <?php WP_Plugin_Dependencies::display_admin_notice_for_unmet_dependencies(); ?> 765 <?php WP_Plugin_Dependencies::display_admin_notice_for_circular_dependencies(); ?> 766 <div class="wrap"> 767 <h1 class="wp-heading-inline"> 768 <?php 769 echo esc_html( $title ); 770 ?> 771 </h1> 772 773 <?php 774 if ( ( ! is_multisite() || is_network_admin() ) && current_user_can( 'install_plugins' ) ) { 775 ?> 776 <a href="<?php echo esc_url( self_admin_url( 'plugin-install.php' ) ); ?>" class="page-title-action"><?php echo esc_html__( 'Add Plugin' ); ?></a> 777 <?php 778 } 779 780 if ( strlen( $s ) ) { 781 echo '<span class="subtitle">'; 782 printf( 783 /* translators: %s: Search query. */ 784 __( 'Search results for: %s' ), 785 '<strong>' . esc_html( urldecode( $s ) ) . '</strong>' 786 ); 787 echo '</span>'; 788 } 789 ?> 790 791 <hr class="wp-header-end"> 792 793 <?php 794 /** 795 * Fires before the plugins list table is rendered. 796 * 797 * This hook also fires before the plugins list table is rendered in the Network Admin. 798 * 799 * Please note: The 'active' portion of the hook name does not refer to whether the current 800 * view is for active plugins, but rather all plugins actively-installed. 801 * 802 * @since 3.0.0 803 * 804 * @param array[] $plugins_all An array of arrays containing information on all installed plugins. 805 */ 806 do_action( 'pre_current_active_plugins', $plugins['all'] ); 807 ?> 808 809 <?php $wp_list_table->views(); ?> 810 811 <form class="search-form search-plugins" method="get"> 812 <?php $wp_list_table->search_box( __( 'Search installed plugins' ), 'plugin' ); ?> 813 </form> 814 815 <form method="post" id="bulk-action-form"> 816 817 <input type="hidden" name="plugin_status" value="<?php echo esc_attr( $status ); ?>" /> 818 <input type="hidden" name="paged" value="<?php echo esc_attr( $page ); ?>" /> 819 820 <?php $wp_list_table->display(); ?> 821 </form> 822 823 <span class="spinner"></span> 824 </div> 825 826 <?php 827 wp_print_request_filesystem_credentials_modal(); 828 wp_print_admin_notice_templates(); 829 wp_print_update_row_templates(); 830 831 require_once ABSPATH . 'wp-admin/admin-footer.php';
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated : Wed Nov 11 08:20:02 2026 | Cross-referenced by PHPXref |