wp/wp-admin/plugins.php
changeset 7 cf61fcea0001
parent 5 5e2f62d02dcd
child 9 177826044cd9
equal deleted inserted replaced
6:490d5cc509ed 7:cf61fcea0001
     8 
     8 
     9 /** WordPress Administration Bootstrap */
     9 /** WordPress Administration Bootstrap */
    10 require_once( dirname( __FILE__ ) . '/admin.php' );
    10 require_once( dirname( __FILE__ ) . '/admin.php' );
    11 
    11 
    12 if ( ! current_user_can('activate_plugins') )
    12 if ( ! current_user_can('activate_plugins') )
    13 	wp_die( __( 'You do not have sufficient permissions to manage plugins for this site.' ) );
    13 	wp_die( __( 'Sorry, you are not allowed to manage plugins for this site.' ) );
    14 
    14 
    15 $wp_list_table = _get_list_table('WP_Plugins_List_Table');
    15 $wp_list_table = _get_list_table('WP_Plugins_List_Table');
    16 $pagenum = $wp_list_table->get_pagenum();
    16 $pagenum = $wp_list_table->get_pagenum();
    17 
    17 
    18 $action = $wp_list_table->current_action();
    18 $action = $wp_list_table->current_action();
    19 
    19 
    20 $plugin = isset($_REQUEST['plugin']) ? $_REQUEST['plugin'] : '';
    20 $plugin = isset($_REQUEST['plugin']) ? wp_unslash( $_REQUEST['plugin'] ) : '';
    21 $s = isset($_REQUEST['s']) ? urlencode($_REQUEST['s']) : '';
    21 $s = isset($_REQUEST['s']) ? urlencode( wp_unslash( $_REQUEST['s'] ) ) : '';
    22 
    22 
    23 // Clean up request URI from temporary args for screen options/paging uri's to work as expected.
    23 // Clean up request URI from temporary args for screen options/paging uri's to work as expected.
    24 $_SERVER['REQUEST_URI'] = remove_query_arg(array('error', 'deleted', 'activate', 'activate-multi', 'deactivate', 'deactivate-multi', '_error_nonce'), $_SERVER['REQUEST_URI']);
    24 $_SERVER['REQUEST_URI'] = remove_query_arg(array('error', 'deleted', 'activate', 'activate-multi', 'deactivate', 'deactivate-multi', '_error_nonce'), $_SERVER['REQUEST_URI']);
    25 
    25 
    26 wp_enqueue_script( 'updates' );
    26 wp_enqueue_script( 'updates' );
    27 
    27 
    28 if ( $action ) {
    28 if ( $action ) {
    29 
    29 
    30 	switch ( $action ) {
    30 	switch ( $action ) {
    31 		case 'activate':
    31 		case 'activate':
    32 			if ( ! current_user_can('activate_plugins') )
    32 			if ( ! current_user_can( 'activate_plugin', $plugin ) ) {
    33 				wp_die(__('You do not have sufficient permissions to activate plugins for this site.'));
    33 				wp_die( __( 'Sorry, you are not allowed to activate this plugin.' ) );
       
    34 			}
    34 
    35 
    35 			if ( is_multisite() && ! is_network_admin() && is_network_only_plugin( $plugin ) ) {
    36 			if ( is_multisite() && ! is_network_admin() && is_network_only_plugin( $plugin ) ) {
    36 				wp_redirect( self_admin_url("plugins.php?plugin_status=$status&paged=$page&s=$s") );
    37 				wp_redirect( self_admin_url("plugins.php?plugin_status=$status&paged=$page&s=$s") );
    37 				exit;
    38 				exit;
    38 			}
    39 			}
    39 
    40 
    40 			check_admin_referer('activate-plugin_' . $plugin);
    41 			check_admin_referer('activate-plugin_' . $plugin);
    41 
    42 
    42 			$result = activate_plugin($plugin, self_admin_url('plugins.php?error=true&plugin=' . $plugin), is_network_admin() );
    43 			$result = activate_plugin($plugin, self_admin_url('plugins.php?error=true&plugin=' . urlencode( $plugin ) ), is_network_admin() );
    43 			if ( is_wp_error( $result ) ) {
    44 			if ( is_wp_error( $result ) ) {
    44 				if ( 'unexpected_output' == $result->get_error_code() ) {
    45 				if ( 'unexpected_output' == $result->get_error_code() ) {
    45 					$redirect = self_admin_url('plugins.php?error=true&charsout=' . strlen($result->get_error_data()) . '&plugin=' . $plugin . "&plugin_status=$status&paged=$page&s=$s");
    46 					$redirect = self_admin_url('plugins.php?error=true&charsout=' . strlen($result->get_error_data()) . '&plugin=' . urlencode( $plugin ) . "&plugin_status=$status&paged=$page&s=$s");
    46 					wp_redirect(add_query_arg('_error_nonce', wp_create_nonce('plugin-activation-error_' . $plugin), $redirect));
    47 					wp_redirect(add_query_arg('_error_nonce', wp_create_nonce('plugin-activation-error_' . $plugin), $redirect));
    47 					exit;
    48 					exit;
    48 				} else {
    49 				} else {
    49 					wp_die($result);
    50 					wp_die($result);
    50 				}
    51 				}
    52 
    53 
    53 			if ( ! is_network_admin() ) {
    54 			if ( ! is_network_admin() ) {
    54 				$recent = (array) get_option( 'recently_activated' );
    55 				$recent = (array) get_option( 'recently_activated' );
    55 				unset( $recent[ $plugin ] );
    56 				unset( $recent[ $plugin ] );
    56 				update_option( 'recently_activated', $recent );
    57 				update_option( 'recently_activated', $recent );
       
    58 			} else {
       
    59 				$recent = (array) get_site_option( 'recently_activated' );
       
    60 				unset( $recent[ $plugin ] );
       
    61 				update_site_option( 'recently_activated', $recent );
    57 			}
    62 			}
    58 
    63 
    59 			if ( isset($_GET['from']) && 'import' == $_GET['from'] ) {
    64 			if ( isset($_GET['from']) && 'import' == $_GET['from'] ) {
    60 				wp_redirect( self_admin_url("import.php?import=" . str_replace('-importer', '', dirname($plugin))) ); // overrides the ?error=true one above and redirects to the Imports page, stripping the -importer suffix
    65 				wp_redirect( self_admin_url("import.php?import=" . str_replace('-importer', '', dirname($plugin))) ); // overrides the ?error=true one above and redirects to the Imports page, stripping the -importer suffix
       
    66 			} else if ( isset($_GET['from']) && 'press-this' == $_GET['from'] ) {
       
    67 				wp_redirect( self_admin_url( "press-this.php") );
       
    68 			} else if ( isset( $_GET['from'] ) && 'try-gutenberg' == $_GET['from'] ) {
       
    69 				if ( 'gutenberg/gutenberg.php' === $plugin ) {
       
    70 					wp_redirect( self_admin_url( "admin.php?page=gutenberg" ) );
       
    71 				} else {
       
    72 					wp_redirect( self_admin_url() );
       
    73 				}
    61 			} else {
    74 			} else {
    62 				wp_redirect( self_admin_url("plugins.php?activate=true&plugin_status=$status&paged=$page&s=$s") ); // overrides the ?error=true one above
    75 				wp_redirect( self_admin_url("plugins.php?activate=true&plugin_status=$status&paged=$page&s=$s") ); // overrides the ?error=true one above
    63 			}
    76 			}
    64 			exit;
    77 			exit;
    65 
    78 
    66 		case 'activate-selected':
    79 		case 'activate-selected':
    67 			if ( ! current_user_can('activate_plugins') )
    80 			if ( ! current_user_can('activate_plugins') )
    68 				wp_die(__('You do not have sufficient permissions to activate plugins for this site.'));
    81 				wp_die(__('Sorry, you are not allowed to activate plugins for this site.'));
    69 
    82 
    70 			check_admin_referer('bulk-plugins');
    83 			check_admin_referer('bulk-plugins');
    71 
    84 
    72 			$plugins = isset( $_POST['checked'] ) ? (array) $_POST['checked'] : array();
    85 			$plugins = isset( $_POST['checked'] ) ? (array) wp_unslash( $_POST['checked'] ) : array();
    73 
    86 
    74 			if ( is_network_admin() ) {
    87 			if ( is_network_admin() ) {
    75 				foreach ( $plugins as $i => $plugin ) {
    88 				foreach ( $plugins as $i => $plugin ) {
    76 					// Only activate plugins which are not already network activated.
    89 					// Only activate plugins which are not already network activated.
    77 					if ( is_plugin_active_for_network( $plugin ) ) {
    90 					if ( is_plugin_active_for_network( $plugin ) ) {
    82 				foreach ( $plugins as $i => $plugin ) {
    95 				foreach ( $plugins as $i => $plugin ) {
    83 					// Only activate plugins which are not already active and are not network-only when on Multisite.
    96 					// Only activate plugins which are not already active and are not network-only when on Multisite.
    84 					if ( is_plugin_active( $plugin ) || ( is_multisite() && is_network_only_plugin( $plugin ) ) ) {
    97 					if ( is_plugin_active( $plugin ) || ( is_multisite() && is_network_only_plugin( $plugin ) ) ) {
    85 						unset( $plugins[ $i ] );
    98 						unset( $plugins[ $i ] );
    86 					}
    99 					}
       
   100 					// Only activate plugins which the user can activate.
       
   101 					if ( ! current_user_can( 'activate_plugin', $plugin ) ) {
       
   102 						unset( $plugins[ $i ] );
       
   103 					}
    87 				}
   104 				}
    88 			}
   105 			}
    89 
   106 
    90 			if ( empty($plugins) ) {
   107 			if ( empty($plugins) ) {
    91 				wp_redirect( self_admin_url("plugins.php?plugin_status=$status&paged=$page&s=$s") );
   108 				wp_redirect( self_admin_url("plugins.php?plugin_status=$status&paged=$page&s=$s") );
    94 
   111 
    95 			activate_plugins($plugins, self_admin_url('plugins.php?error=true'), is_network_admin() );
   112 			activate_plugins($plugins, self_admin_url('plugins.php?error=true'), is_network_admin() );
    96 
   113 
    97 			if ( ! is_network_admin() ) {
   114 			if ( ! is_network_admin() ) {
    98 				$recent = (array) get_option('recently_activated' );
   115 				$recent = (array) get_option('recently_activated' );
    99 				foreach ( $plugins as $plugin )
   116 			} else {
   100 					unset( $recent[ $plugin ] );
   117 				$recent = (array) get_site_option('recently_activated' );
       
   118 			}
       
   119 
       
   120 			foreach ( $plugins as $plugin ) {
       
   121 				unset( $recent[ $plugin ] );
       
   122 			}
       
   123 
       
   124 			if ( ! is_network_admin() ) {
   101 				update_option( 'recently_activated', $recent );
   125 				update_option( 'recently_activated', $recent );
       
   126 			} else {
       
   127 				update_site_option( 'recently_activated', $recent );
   102 			}
   128 			}
   103 
   129 
   104 			wp_redirect( self_admin_url("plugins.php?activate-multi=true&plugin_status=$status&paged=$page&s=$s") );
   130 			wp_redirect( self_admin_url("plugins.php?activate-multi=true&plugin_status=$status&paged=$page&s=$s") );
   105 			exit;
   131 			exit;
   106 
   132 
   107 		case 'update-selected' :
   133 		case 'update-selected' :
   108 
   134 
   109 			check_admin_referer( 'bulk-plugins' );
   135 			check_admin_referer( 'bulk-plugins' );
   110 
   136 
   111 			if ( isset( $_GET['plugins'] ) )
   137 			if ( isset( $_GET['plugins'] ) )
   112 				$plugins = explode( ',', $_GET['plugins'] );
   138 				$plugins = explode( ',', wp_unslash( $_GET['plugins'] ) );
   113 			elseif ( isset( $_POST['checked'] ) )
   139 			elseif ( isset( $_POST['checked'] ) )
   114 				$plugins = (array) $_POST['checked'];
   140 				$plugins = (array) wp_unslash( $_POST['checked'] );
   115 			else
   141 			else
   116 				$plugins = array();
   142 				$plugins = array();
   117 
   143 
   118 			$title = __( 'Update Plugins' );
   144 			$title = __( 'Update Plugins' );
   119 			$parent_file = 'plugins.php';
   145 			$parent_file = 'plugins.php';
   120 
   146 
   121 			wp_enqueue_script( 'updates' );
   147 			wp_enqueue_script( 'updates' );
   122 			require_once(ABSPATH . 'wp-admin/admin-header.php');
   148 			require_once(ABSPATH . 'wp-admin/admin-header.php');
   123 
   149 
   124 			echo '<div class="wrap">';
   150 			echo '<div class="wrap">';
   125 			echo '<h2>' . esc_html( $title ) . '</h2>';
   151 			echo '<h1>' . esc_html( $title ) . '</h1>';
   126 
   152 
   127 			$url = self_admin_url('update.php?action=update-selected&amp;plugins=' . urlencode( join(',', $plugins) ));
   153 			$url = self_admin_url('update.php?action=update-selected&amp;plugins=' . urlencode( join(',', $plugins) ));
   128 			$url = wp_nonce_url($url, 'bulk-update-plugins');
   154 			$url = wp_nonce_url($url, 'bulk-update-plugins');
   129 
   155 
   130 			echo "<iframe src='$url' style='width: 100%; height:100%; min-height:850px;'></iframe>";
   156 			echo "<iframe src='$url' style='width: 100%; height:100%; min-height:850px;'></iframe>";
   131 			echo '</div>';
   157 			echo '</div>';
   132 			require_once(ABSPATH . 'wp-admin/admin-footer.php');
   158 			require_once(ABSPATH . 'wp-admin/admin-footer.php');
   133 			exit;
   159 			exit;
   134 
   160 
   135 		case 'error_scrape':
   161 		case 'error_scrape':
   136 			if ( ! current_user_can('activate_plugins') )
   162 			if ( ! current_user_can( 'activate_plugin', $plugin ) ) {
   137 				wp_die(__('You do not have sufficient permissions to activate plugins for this site.'));
   163 				wp_die( __( 'Sorry, you are not allowed to activate this plugin.' ) );
       
   164 			}
   138 
   165 
   139 			check_admin_referer('plugin-activation-error_' . $plugin);
   166 			check_admin_referer('plugin-activation-error_' . $plugin);
   140 
   167 
   141 			$valid = validate_plugin($plugin);
   168 			$valid = validate_plugin($plugin);
   142 			if ( is_wp_error($valid) )
   169 			if ( is_wp_error($valid) )
   146 				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 );
   173 				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 );
   147 			}
   174 			}
   148 
   175 
   149 			@ini_set('display_errors', true); //Ensure that Fatal errors are displayed.
   176 			@ini_set('display_errors', true); //Ensure that Fatal errors are displayed.
   150 			// Go back to "sandbox" scope so we get the same errors as before
   177 			// Go back to "sandbox" scope so we get the same errors as before
   151 			function plugin_sandbox_scrape( $plugin ) {
       
   152 				wp_register_plugin_realpath( WP_PLUGIN_DIR . '/' . $plugin );
       
   153 				include( WP_PLUGIN_DIR . '/' . $plugin );
       
   154 			}
       
   155 			plugin_sandbox_scrape( $plugin );
   178 			plugin_sandbox_scrape( $plugin );
   156 			/** This action is documented in wp-admin/includes/plugin.php */
   179 			/** This action is documented in wp-admin/includes/plugin.php */
   157 			do_action( "activate_{$plugin}" );
   180 			do_action( "activate_{$plugin}" );
   158 			exit;
   181 			exit;
   159 
   182 
   160 		case 'deactivate':
   183 		case 'deactivate':
   161 			if ( ! current_user_can('activate_plugins') )
   184 			if ( ! current_user_can( 'deactivate_plugin', $plugin ) ) {
   162 				wp_die(__('You do not have sufficient permissions to deactivate plugins for this site.'));
   185 				wp_die( __( 'Sorry, you are not allowed to deactivate this plugin.' ) );
       
   186 			}
   163 
   187 
   164 			check_admin_referer('deactivate-plugin_' . $plugin);
   188 			check_admin_referer('deactivate-plugin_' . $plugin);
   165 
   189 
   166 			if ( ! is_network_admin() && is_plugin_active_for_network( $plugin ) ) {
   190 			if ( ! is_network_admin() && is_plugin_active_for_network( $plugin ) ) {
   167 				wp_redirect( self_admin_url("plugins.php?plugin_status=$status&paged=$page&s=$s") );
   191 				wp_redirect( self_admin_url("plugins.php?plugin_status=$status&paged=$page&s=$s") );
   168 				exit;
   192 				exit;
   169 			}
   193 			}
   170 
   194 
   171 			deactivate_plugins( $plugin, false, is_network_admin() );
   195 			deactivate_plugins( $plugin, false, is_network_admin() );
   172 			if ( ! is_network_admin() )
   196 
       
   197 			if ( ! is_network_admin() ) {
   173 				update_option( 'recently_activated', array( $plugin => time() ) + (array) get_option( 'recently_activated' ) );
   198 				update_option( 'recently_activated', array( $plugin => time() ) + (array) get_option( 'recently_activated' ) );
       
   199 			} else {
       
   200 				update_site_option( 'recently_activated', array( $plugin => time() ) + (array) get_site_option( 'recently_activated' ) );
       
   201 			}
       
   202 
   174 			if ( headers_sent() )
   203 			if ( headers_sent() )
   175 				echo "<meta http-equiv='refresh' content='" . esc_attr( "0;url=plugins.php?deactivate=true&plugin_status=$status&paged=$page&s=$s" ) . "' />";
   204 				echo "<meta http-equiv='refresh' content='" . esc_attr( "0;url=plugins.php?deactivate=true&plugin_status=$status&paged=$page&s=$s" ) . "' />";
   176 			else
   205 			else
   177 				wp_redirect( self_admin_url("plugins.php?deactivate=true&plugin_status=$status&paged=$page&s=$s") );
   206 				wp_redirect( self_admin_url("plugins.php?deactivate=true&plugin_status=$status&paged=$page&s=$s") );
   178 			exit;
   207 			exit;
   179 
   208 
   180 		case 'deactivate-selected':
   209 		case 'deactivate-selected':
   181 			if ( ! current_user_can('activate_plugins') )
   210 			if ( ! current_user_can( 'deactivate_plugins' ) ) {
   182 				wp_die(__('You do not have sufficient permissions to deactivate plugins for this site.'));
   211 				wp_die(__('Sorry, you are not allowed to deactivate plugins for this site.'));
       
   212 			}
   183 
   213 
   184 			check_admin_referer('bulk-plugins');
   214 			check_admin_referer('bulk-plugins');
   185 
   215 
   186 			$plugins = isset( $_POST['checked'] ) ? (array) $_POST['checked'] : array();
   216 			$plugins = isset( $_POST['checked'] ) ? (array) wp_unslash( $_POST['checked'] ) : array();
   187 			// Do not deactivate plugins which are already deactivated.
   217 			// Do not deactivate plugins which are already deactivated.
   188 			if ( is_network_admin() ) {
   218 			if ( is_network_admin() ) {
   189 				$plugins = array_filter( $plugins, 'is_plugin_active_for_network' );
   219 				$plugins = array_filter( $plugins, 'is_plugin_active_for_network' );
   190 			} else {
   220 			} else {
   191 				$plugins = array_filter( $plugins, 'is_plugin_active' );
   221 				$plugins = array_filter( $plugins, 'is_plugin_active' );
   192 				$plugins = array_diff( $plugins, array_filter( $plugins, 'is_plugin_active_for_network' ) );
   222 				$plugins = array_diff( $plugins, array_filter( $plugins, 'is_plugin_active_for_network' ) );
       
   223 
       
   224 				foreach ( $plugins as $i => $plugin ) {
       
   225 					// Only deactivate plugins which the user can deactivate.
       
   226 					if ( ! current_user_can( 'deactivate_plugin', $plugin ) ) {
       
   227 						unset( $plugins[ $i ] );
       
   228 					}
       
   229 				}
       
   230 
   193 			}
   231 			}
   194 			if ( empty($plugins) ) {
   232 			if ( empty($plugins) ) {
   195 				wp_redirect( self_admin_url("plugins.php?plugin_status=$status&paged=$page&s=$s") );
   233 				wp_redirect( self_admin_url("plugins.php?plugin_status=$status&paged=$page&s=$s") );
   196 				exit;
   234 				exit;
   197 			}
   235 			}
   198 
   236 
   199 			deactivate_plugins( $plugins, false, is_network_admin() );
   237 			deactivate_plugins( $plugins, false, is_network_admin() );
   200 
   238 
       
   239 			$deactivated = array();
       
   240 			foreach ( $plugins as $plugin ) {
       
   241 				$deactivated[ $plugin ] = time();
       
   242 			}
       
   243 
   201 			if ( ! is_network_admin() ) {
   244 			if ( ! is_network_admin() ) {
   202 				$deactivated = array();
       
   203 				foreach ( $plugins as $plugin )
       
   204 					$deactivated[ $plugin ] = time();
       
   205 				update_option( 'recently_activated', $deactivated + (array) get_option( 'recently_activated' ) );
   245 				update_option( 'recently_activated', $deactivated + (array) get_option( 'recently_activated' ) );
       
   246 			} else {
       
   247 				update_site_option( 'recently_activated', $deactivated + (array) get_site_option( 'recently_activated' ) );
   206 			}
   248 			}
   207 
   249 
   208 			wp_redirect( self_admin_url("plugins.php?deactivate-multi=true&plugin_status=$status&paged=$page&s=$s") );
   250 			wp_redirect( self_admin_url("plugins.php?deactivate-multi=true&plugin_status=$status&paged=$page&s=$s") );
   209 			exit;
   251 			exit;
   210 
   252 
   211 		case 'delete-selected':
   253 		case 'delete-selected':
   212 			if ( ! current_user_can('delete_plugins') ) {
   254 			if ( ! current_user_can('delete_plugins') ) {
   213 				wp_die(__('You do not have sufficient permissions to delete plugins for this site.'));
   255 				wp_die(__('Sorry, you are not allowed to delete plugins for this site.'));
   214 			}
   256 			}
   215 
   257 
   216 			check_admin_referer('bulk-plugins');
   258 			check_admin_referer('bulk-plugins');
   217 
   259 
   218 			//$_POST = from the plugin form; $_GET = from the FTP details screen.
   260 			//$_POST = from the plugin form; $_GET = from the FTP details screen.
   219 			$plugins = isset( $_REQUEST['checked'] ) ? (array) $_REQUEST['checked'] : array();
   261 			$plugins = isset( $_REQUEST['checked'] ) ? (array) wp_unslash( $_REQUEST['checked'] ) : array();
   220 			if ( empty( $plugins ) ) {
   262 			if ( empty( $plugins ) ) {
   221 				wp_redirect( self_admin_url("plugins.php?plugin_status=$status&paged=$page&s=$s") );
   263 				wp_redirect( self_admin_url("plugins.php?plugin_status=$status&paged=$page&s=$s") );
   222 				exit;
   264 				exit;
   223 			}
   265 			}
   224 
   266 
   225 			$plugins = array_filter($plugins, 'is_plugin_inactive'); // Do not allow to delete Activated plugins.
   267 			$plugins = array_filter($plugins, 'is_plugin_inactive'); // Do not allow to delete Activated plugins.
   226 			if ( empty( $plugins ) ) {
   268 			if ( empty( $plugins ) ) {
   227 				wp_redirect( self_admin_url( "plugins.php?error=true&main=true&plugin_status=$status&paged=$page&s=$s" ) );
   269 				wp_redirect( self_admin_url( "plugins.php?error=true&main=true&plugin_status=$status&paged=$page&s=$s" ) );
       
   270 				exit;
       
   271 			}
       
   272 
       
   273 			// Bail on all if any paths are invalid.
       
   274 			// validate_file() returns truthy for invalid files
       
   275 			$invalid_plugin_files = array_filter( $plugins, 'validate_file' );
       
   276 			if ( $invalid_plugin_files ) {
       
   277 				wp_redirect( self_admin_url("plugins.php?plugin_status=$status&paged=$page&s=$s") );
   228 				exit;
   278 				exit;
   229 			}
   279 			}
   230 
   280 
   231 			include(ABSPATH . 'wp-admin/update.php');
   281 			include(ABSPATH . 'wp-admin/update.php');
   232 
   282 
   236 				wp_enqueue_script('jquery');
   286 				wp_enqueue_script('jquery');
   237 				require_once(ABSPATH . 'wp-admin/admin-header.php');
   287 				require_once(ABSPATH . 'wp-admin/admin-header.php');
   238 				?>
   288 				?>
   239 			<div class="wrap">
   289 			<div class="wrap">
   240 				<?php
   290 				<?php
   241 					$files_to_delete = $plugin_info = array();
   291 					$plugin_info = array();
   242 					$have_non_network_plugins = false;
   292 					$have_non_network_plugins = false;
   243 					$plugin_translations = wp_get_installed_translations( 'plugins' );
       
   244 					foreach ( (array) $plugins as $plugin ) {
   293 					foreach ( (array) $plugins as $plugin ) {
   245 						$plugin_slug = dirname( $plugin );
   294 						$plugin_slug = dirname( $plugin );
   246 
   295 
   247 						if ( '.' == $plugin_slug ) {
   296 						if ( '.' == $plugin_slug ) {
   248 							$files_to_delete[] = WP_PLUGIN_DIR . '/' . $plugin;
       
   249 							if ( $data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin ) ) {
   297 							if ( $data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin ) ) {
   250 								$plugin_info[ $plugin ] = $data;
   298 								$plugin_info[ $plugin ] = $data;
   251 								$plugin_info[ $plugin ]['is_uninstallable'] = is_uninstallable_plugin( $plugin );
   299 								$plugin_info[ $plugin ]['is_uninstallable'] = is_uninstallable_plugin( $plugin );
   252 								if ( ! $plugin_info[ $plugin ]['Network'] ) {
   300 								if ( ! $plugin_info[ $plugin ]['Network'] ) {
   253 									$have_non_network_plugins = true;
   301 									$have_non_network_plugins = true;
   254 								}
   302 								}
   255 							}
   303 							}
   256 						} else {
   304 						} else {
   257 							// Locate all the files in that folder.
       
   258 							$files = list_files( WP_PLUGIN_DIR . '/' . $plugin_slug );
       
   259 							if ( $files ) {
       
   260 								$files_to_delete = array_merge( $files_to_delete, $files );
       
   261 							}
       
   262 
       
   263 							// Get plugins list from that folder.
   305 							// Get plugins list from that folder.
   264 							if ( $folder_plugins = get_plugins( '/' . $plugin_slug ) ) {
   306 							if ( $folder_plugins = get_plugins( '/' . $plugin_slug ) ) {
   265 								foreach( $folder_plugins as $plugin_file => $data ) {
   307 								foreach ( $folder_plugins as $plugin_file => $data ) {
   266 									$plugin_info[ $plugin_file ] = _get_plugin_data_markup_translate( $plugin_file, $data );
   308 									$plugin_info[ $plugin_file ] = _get_plugin_data_markup_translate( $plugin_file, $data );
   267 									$plugin_info[ $plugin_file ]['is_uninstallable'] = is_uninstallable_plugin( $plugin );
   309 									$plugin_info[ $plugin_file ]['is_uninstallable'] = is_uninstallable_plugin( $plugin );
   268 									if ( ! $plugin_info[ $plugin_file ]['Network'] ) {
   310 									if ( ! $plugin_info[ $plugin_file ]['Network'] ) {
   269 										$have_non_network_plugins = true;
   311 										$have_non_network_plugins = true;
   270 									}
   312 									}
   271 								}
   313 								}
   272 							}
   314 							}
   273 
       
   274 							// Add translation files.
       
   275 							if ( ! empty( $plugin_translations[ $plugin_slug ] ) ) {
       
   276 								$translations = $plugin_translations[ $plugin_slug ];
       
   277 
       
   278 								foreach ( $translations as $translation => $data ) {
       
   279 									$files_to_delete[] = $plugin_slug . '-' . $translation . '.po';
       
   280 									$files_to_delete[] = $plugin_slug . '-' . $translation . '.mo';
       
   281 								}
       
   282 							}
       
   283 						}
   315 						}
   284 					}
   316 					}
   285 					$plugins_to_delete = count( $plugin_info );
   317 					$plugins_to_delete = count( $plugin_info );
   286 				?>
   318 				?>
   287 				<?php if ( 1 == $plugins_to_delete ) : ?>
   319 				<?php if ( 1 == $plugins_to_delete ) : ?>
   288 					<h2><?php _e( 'Delete Plugin' ); ?></h2>
   320 					<h1><?php _e( 'Delete Plugin' ); ?></h1>
   289 					<?php if ( $have_non_network_plugins && is_network_admin() ) : ?>
   321 					<?php if ( $have_non_network_plugins && is_network_admin() ) : ?>
   290 						<div class="error"><p><strong><?php _e( 'Caution:' ); ?></strong> <?php _e( 'This plugin may be active on other sites in the network.' ); ?></p></div>
   322 						<div class="error"><p><strong><?php _e( 'Caution:' ); ?></strong> <?php _e( 'This plugin may be active on other sites in the network.' ); ?></p></div>
   291 					<?php endif; ?>
   323 					<?php endif; ?>
   292 					<p><?php _e( 'You are about to remove the following plugin:' ); ?></p>
   324 					<p><?php _e( 'You are about to remove the following plugin:' ); ?></p>
   293 				<?php else: ?>
   325 				<?php else: ?>
   294 					<h2><?php _e( 'Delete Plugins' ); ?></h2>
   326 					<h1><?php _e( 'Delete Plugins' ); ?></h1>
   295 					<?php if ( $have_non_network_plugins && is_network_admin() ) : ?>
   327 					<?php if ( $have_non_network_plugins && is_network_admin() ) : ?>
   296 						<div class="error"><p><strong><?php _e( 'Caution:' ); ?></strong> <?php _e( 'These plugins may be active on other sites in the network.' ); ?></p></div>
   328 						<div class="error"><p><strong><?php _e( 'Caution:' ); ?></strong> <?php _e( 'These plugins may be active on other sites in the network.' ); ?></p></div>
   297 					<?php endif; ?>
   329 					<?php endif; ?>
   298 					<p><?php _e( 'You are about to remove the following plugins:' ); ?></p>
   330 					<p><?php _e( 'You are about to remove the following plugins:' ); ?></p>
   299 				<?php endif; ?>
   331 				<?php endif; ?>
   301 						<?php
   333 						<?php
   302 						$data_to_delete = false;
   334 						$data_to_delete = false;
   303 						foreach ( $plugin_info as $plugin ) {
   335 						foreach ( $plugin_info as $plugin ) {
   304 							if ( $plugin['is_uninstallable'] ) {
   336 							if ( $plugin['is_uninstallable'] ) {
   305 								/* translators: 1: plugin name, 2: plugin author */
   337 								/* translators: 1: plugin name, 2: plugin author */
   306 								echo '<li>', sprintf( __( '<strong>%1$s</strong> by <em>%2$s</em> (will also <strong>delete its data</strong>)' ), esc_html($plugin['Name']), esc_html($plugin['AuthorName']) ), '</li>';
   338 								echo '<li>', sprintf( __( '%1$s by %2$s (will also <strong>delete its data</strong>)' ), '<strong>' . $plugin['Name'] . '</strong>', '<em>' . $plugin['AuthorName'] . '</em>' ), '</li>';
   307 								$data_to_delete = true;
   339 								$data_to_delete = true;
   308 							} else {
   340 							} else {
   309 								/* translators: 1: plugin name, 2: plugin author */
   341 								/* translators: 1: plugin name, 2: plugin author */
   310 								echo '<li>', sprintf( __('<strong>%1$s</strong> by <em>%2$s</em>' ), esc_html($plugin['Name']), esc_html($plugin['AuthorName']) ), '</li>';
   342 								echo '<li>', sprintf( _x('%1$s by %2$s', 'plugin' ), '<strong>' . $plugin['Name'] . '</strong>', '<em>' . $plugin['AuthorName'] ) . '</em>', '</li>';
   311 							}
   343 							}
   312 						}
   344 						}
   313 						?>
   345 						?>
   314 					</ul>
   346 					</ul>
   315 				<p><?php
   347 				<p><?php
   325 						foreach ( (array) $plugins as $plugin ) {
   357 						foreach ( (array) $plugins as $plugin ) {
   326 							echo '<input type="hidden" name="checked[]" value="' . esc_attr( $plugin ) . '" />';
   358 							echo '<input type="hidden" name="checked[]" value="' . esc_attr( $plugin ) . '" />';
   327 						}
   359 						}
   328 					?>
   360 					?>
   329 					<?php wp_nonce_field('bulk-plugins') ?>
   361 					<?php wp_nonce_field('bulk-plugins') ?>
   330 					<?php submit_button( $data_to_delete ? __( 'Yes, Delete these files and data' ) : __( 'Yes, Delete these files' ), 'button', 'submit', false ); ?>
   362 					<?php submit_button( $data_to_delete ? __( 'Yes, delete these files and data' ) : __( 'Yes, delete these files' ), '', 'submit', false ); ?>
   331 				</form>
   363 				</form>
   332 				<?php
   364 				<?php
   333 				$referer = wp_get_referer();
   365 				$referer = wp_get_referer();
   334 				?>
   366 				?>
   335 				<form method="post" action="<?php echo $referer ? esc_url( $referer ) : ''; ?>" style="display:inline;">
   367 				<form method="post" action="<?php echo $referer ? esc_url( $referer ) : ''; ?>" style="display:inline;">
   336 					<?php submit_button( __( 'No, Return me to the plugin list' ), 'button', 'submit', false ); ?>
   368 					<?php submit_button( __( 'No, return me to the plugin list' ), '', 'submit', false ); ?>
   337 				</form>
   369 				</form>
   338 
       
   339 				<p><a href="#" onclick="jQuery('#files-list').toggle(); return false;"><?php _e('Click to view entire list of files which will be deleted'); ?></a></p>
       
   340 				<div id="files-list" style="display:none;">
       
   341 					<ul class="code">
       
   342 					<?php
       
   343 						foreach ( (array) $files_to_delete as $file ) {
       
   344 							echo '<li>' . esc_html( str_replace( WP_PLUGIN_DIR, '', $file ) ) . '</li>';
       
   345 						}
       
   346 					?>
       
   347 					</ul>
       
   348 				</div>
       
   349 			</div>
   370 			</div>
   350 				<?php
   371 				<?php
   351 				require_once(ABSPATH . 'wp-admin/admin-footer.php');
   372 				require_once(ABSPATH . 'wp-admin/admin-footer.php');
   352 				exit;
   373 				exit;
   353 			} //Endif verify-delete
   374 			} else {
   354 			$delete_result = delete_plugins($plugins);
   375 				$plugins_to_delete = count( $plugins );
       
   376 			} // endif verify-delete
       
   377 
       
   378 			$delete_result = delete_plugins( $plugins );
   355 
   379 
   356 			set_transient('plugins_delete_result_' . $user_ID, $delete_result); //Store the result in a cache rather than a URL param due to object type & length
   380 			set_transient('plugins_delete_result_' . $user_ID, $delete_result); //Store the result in a cache rather than a URL param due to object type & length
   357 			wp_redirect( self_admin_url("plugins.php?deleted=true&plugin_status=$status&paged=$page&s=$s") );
   381 			wp_redirect( self_admin_url("plugins.php?deleted=$plugins_to_delete&plugin_status=$status&paged=$page&s=$s") );
   358 			exit;
   382 			exit;
   359 
   383 
   360 		case 'clear-recent-list':
   384 		case 'clear-recent-list':
   361 			if ( ! is_network_admin() )
   385 			if ( ! is_network_admin() ) {
   362 				update_option( 'recently_activated', array() );
   386 				update_option( 'recently_activated', array() );
       
   387 			} else {
       
   388 				update_site_option( 'recently_activated', array() );
       
   389 			}
       
   390 			break;
       
   391 
       
   392 		default:
       
   393 			if ( isset( $_POST['checked'] ) ) {
       
   394 				check_admin_referer('bulk-plugins');
       
   395 				$plugins = isset( $_POST['checked'] ) ? (array) wp_unslash( $_POST['checked'] ) : array();
       
   396 				$sendback = wp_get_referer();
       
   397 
       
   398 				/** This action is documented in wp-admin/edit-comments.php */
       
   399 				$sendback = apply_filters( 'handle_bulk_actions-' . get_current_screen()->id, $sendback, $action, $plugins );
       
   400 				wp_safe_redirect( $sendback );
       
   401 				exit;
       
   402 			}
   363 			break;
   403 			break;
   364 	}
   404 	}
       
   405 
   365 }
   406 }
   366 
   407 
   367 $wp_list_table->prepare_items();
   408 $wp_list_table->prepare_items();
   368 
   409 
   369 wp_enqueue_script('plugin-install');
   410 wp_enqueue_script('plugin-install');
   374 get_current_screen()->add_help_tab( array(
   415 get_current_screen()->add_help_tab( array(
   375 'id'		=> 'overview',
   416 'id'		=> 'overview',
   376 'title'		=> __('Overview'),
   417 'title'		=> __('Overview'),
   377 'content'	=>
   418 'content'	=>
   378 	'<p>' . __('Plugins extend and expand the functionality of WordPress. Once a plugin is installed, you may activate it or deactivate it here.') . '</p>' .
   419 	'<p>' . __('Plugins extend and expand the functionality of WordPress. Once a plugin is installed, you may activate it or deactivate it here.') . '</p>' .
   379 	'<p>' . sprintf(__('You can find additional plugins for your site by using the <a href="%1$s">Plugin Browser/Installer</a> functionality or by browsing the <a href="%2$s" target="_blank">WordPress Plugin Directory</a> directly and installing new plugins manually. To manually install a plugin you generally just need to upload the plugin file into your <code>/wp-content/plugins</code> directory. Once a plugin has been installed, you can activate it here.'), 'plugin-install.php', 'https://wordpress.org/plugins/') . '</p>'
   420 	'<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>' .
       
   421 	'<p>' . sprintf(
       
   422 		/* translators: %s: WordPress Plugin Directory URL */
       
   423 		__( 'If you would like to see more plugins to choose from, click on the &#8220;Add New&#8221; 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&#8217;re free!' ),
       
   424 		__( 'https://wordpress.org/plugins/' )
       
   425 	) . '</p>'
   380 ) );
   426 ) );
   381 get_current_screen()->add_help_tab( array(
   427 get_current_screen()->add_help_tab( array(
   382 'id'		=> 'compatibility-problems',
   428 'id'		=> 'compatibility-problems',
   383 'title'		=> __('Troubleshooting'),
   429 'title'		=> __('Troubleshooting'),
   384 'content'	=>
   430 'content'	=>
   385 	'<p>' . __('Most of the time, plugins play nicely with the core of WordPress and with other plugins. Sometimes, though, a plugin&#8217;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>' .
   431 	'<p>' . __('Most of the time, plugins play nicely with the core of WordPress and with other plugins. Sometimes, though, a plugin&#8217;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>' .
   386 	'<p>' . sprintf( __('If something goes wrong with a plugin and you can&#8217;t use WordPress, delete or rename that file in the <code>%s</code> directory and it will be automatically deactivated.'), WP_PLUGIN_DIR) . '</p>'
   432 	'<p>' . sprintf(
       
   433 		/* translators: WP_PLUGIN_DIR constant value */
       
   434 		__( 'If something goes wrong with a plugin and you can&#8217;t use WordPress, delete or rename that file in the %s directory and it will be automatically deactivated.' ),
       
   435 		'<code>' . WP_PLUGIN_DIR . '</code>'
       
   436 	) . '</p>'
   387 ) );
   437 ) );
   388 
   438 
   389 get_current_screen()->set_help_sidebar(
   439 get_current_screen()->set_help_sidebar(
   390 	'<p><strong>' . __('For more information:') . '</strong></p>' .
   440 	'<p><strong>' . __('For more information:') . '</strong></p>' .
   391 	'<p>' . __('<a href="https://codex.wordpress.org/Managing_Plugins#Plugin_Management" target="_blank">Documentation on Managing Plugins</a>') . '</p>' .
   441 	'<p>' . __('<a href="https://codex.wordpress.org/Managing_Plugins#Plugin_Management">Documentation on Managing Plugins</a>') . '</p>' .
   392 	'<p>' . __('<a href="https://wordpress.org/support/" target="_blank">Support Forums</a>') . '</p>'
   442 	'<p>' . __('<a href="https://wordpress.org/support/">Support Forums</a>') . '</p>'
   393 );
   443 );
       
   444 
       
   445 get_current_screen()->set_screen_reader_content( array(
       
   446 	'heading_views'      => __( 'Filter plugins list' ),
       
   447 	'heading_pagination' => __( 'Plugins list navigation' ),
       
   448 	'heading_list'       => __( 'Plugins list' ),
       
   449 ) );
   394 
   450 
   395 $title = __('Plugins');
   451 $title = __('Plugins');
   396 $parent_file = 'plugins.php';
   452 $parent_file = 'plugins.php';
   397 
   453 
   398 require_once(ABSPATH . 'wp-admin/admin-header.php');
   454 require_once(ABSPATH . 'wp-admin/admin-header.php');
   399 
   455 
   400 $invalid = validate_active_plugins();
   456 $invalid = validate_active_plugins();
   401 if ( !empty($invalid) )
   457 if ( ! empty( $invalid ) ) {
   402 	foreach ( $invalid as $plugin_file => $error )
   458 	foreach ( $invalid as $plugin_file => $error ) {
   403 		echo '<div id="message" class="error"><p>' . sprintf(__('The plugin <code>%s</code> has been <strong>deactivated</strong> due to an error: %s'), esc_html($plugin_file), $error->get_error_message()) . '</p></div>';
   459 		echo '<div id="message" class="error"><p>';
       
   460 		printf(
       
   461 			/* translators: 1: plugin file 2: error message */
       
   462 			__( 'The plugin %1$s has been <strong>deactivated</strong> due to an error: %2$s' ),
       
   463 			'<code>' . esc_html( $plugin_file ) . '</code>',
       
   464 			$error->get_error_message() );
       
   465 		echo '</p></div>';
       
   466 	}
       
   467 }
   404 ?>
   468 ?>
   405 
   469 
   406 <?php if ( isset($_GET['error']) ) :
   470 <?php if ( isset($_GET['error']) ) :
   407 
   471 
   408 	if ( isset( $_GET['main'] ) )
   472 	if ( isset( $_GET['main'] ) )
   412 	else
   476 	else
   413 		$errmsg = __('Plugin could not be activated because it triggered a <strong>fatal error</strong>.');
   477 		$errmsg = __('Plugin could not be activated because it triggered a <strong>fatal error</strong>.');
   414 	?>
   478 	?>
   415 	<div id="message" class="error"><p><?php echo $errmsg; ?></p>
   479 	<div id="message" class="error"><p><?php echo $errmsg; ?></p>
   416 	<?php
   480 	<?php
   417 		if ( !isset( $_GET['main'] ) && !isset($_GET['charsout']) && wp_verify_nonce($_GET['_error_nonce'], 'plugin-activation-error_' . $plugin) ) { ?>
   481 		if ( ! isset( $_GET['main'] ) && ! isset( $_GET['charsout'] ) && wp_verify_nonce( $_GET['_error_nonce'], 'plugin-activation-error_' . $plugin ) ) {
   418 	<iframe style="border:0" width="100%" height="70px" src="<?php echo 'plugins.php?action=error_scrape&amp;plugin=' . esc_attr($plugin) . '&amp;_wpnonce=' . esc_attr($_GET['_error_nonce']); ?>"></iframe>
   482 			$iframe_url = add_query_arg( array(
       
   483 				'action'   => 'error_scrape',
       
   484 				'plugin'   => urlencode( $plugin ),
       
   485 				'_wpnonce' => urlencode( $_GET['_error_nonce'] ),
       
   486 			), admin_url( 'plugins.php' ) );
       
   487 		?>
       
   488 		<iframe style="border:0" width="100%" height="70px" src="<?php echo esc_url( $iframe_url ); ?>"></iframe>
   419 	<?php
   489 	<?php
   420 		}
   490 		}
   421 	?>
   491 	?>
   422 	</div>
   492 	</div>
   423 <?php elseif ( isset($_GET['deleted']) ) :
   493 <?php elseif ( isset($_GET['deleted']) ) :
   426 		delete_transient( 'plugins_delete_result_' . $user_ID );
   496 		delete_transient( 'plugins_delete_result_' . $user_ID );
   427 
   497 
   428 		if ( is_wp_error($delete_result) ) : ?>
   498 		if ( is_wp_error($delete_result) ) : ?>
   429 		<div id="message" class="error notice is-dismissible"><p><?php printf( __('Plugin could not be deleted due to an error: %s'), $delete_result->get_error_message() ); ?></p></div>
   499 		<div id="message" class="error notice is-dismissible"><p><?php printf( __('Plugin could not be deleted due to an error: %s'), $delete_result->get_error_message() ); ?></p></div>
   430 		<?php else : ?>
   500 		<?php else : ?>
   431 		<div id="message" class="updated notice is-dismissible"><p><?php _e('The selected plugins have been <strong>deleted</strong>.'); ?></p></div>
   501 		<div id="message" class="updated notice is-dismissible">
       
   502 			<p>
       
   503 				<?php
       
   504 				if ( 1 == (int) $_GET['deleted'] ) {
       
   505 					_e( 'The selected plugin has been <strong>deleted</strong>.' );
       
   506 				} else {
       
   507 					_e( 'The selected plugins have been <strong>deleted</strong>.' );
       
   508 				}
       
   509 				?>
       
   510 			</p>
       
   511 		</div>
   432 		<?php endif; ?>
   512 		<?php endif; ?>
   433 <?php elseif ( isset($_GET['activate']) ) : ?>
   513 <?php elseif ( isset($_GET['activate']) ) : ?>
   434 	<div id="message" class="updated notice is-dismissible"><p><?php _e('Plugin <strong>activated</strong>.') ?></p></div>
   514 	<div id="message" class="updated notice is-dismissible"><p><?php _e('Plugin <strong>activated</strong>.') ?></p></div>
   435 <?php elseif (isset($_GET['activate-multi'])) : ?>
   515 <?php elseif (isset($_GET['activate-multi'])) : ?>
   436 	<div id="message" class="updated notice is-dismissible"><p><?php _e('Selected plugins <strong>activated</strong>.'); ?></p></div>
   516 	<div id="message" class="updated notice is-dismissible"><p><?php _e('Selected plugins <strong>activated</strong>.'); ?></p></div>
   437 <?php elseif ( isset($_GET['deactivate']) ) : ?>
   517 <?php elseif ( isset($_GET['deactivate']) ) : ?>
   438 	<div id="message" class="updated notice is-dismissible"><p><?php _e('Plugin <strong>deactivated</strong>.') ?></p></div>
   518 	<div id="message" class="updated notice is-dismissible"><p><?php _e('Plugin <strong>deactivated</strong>.') ?></p></div>
   439 <?php elseif (isset($_GET['deactivate-multi'])) : ?>
   519 <?php elseif (isset($_GET['deactivate-multi'])) : ?>
   440 	<div id="message" class="updated notice is-dismissible"><p><?php _e('Selected plugins <strong>deactivated</strong>.'); ?></p></div>
   520 	<div id="message" class="updated notice is-dismissible"><p><?php _e('Selected plugins <strong>deactivated</strong>.'); ?></p></div>
   441 <?php elseif ( 'update-selected' == $action ) : ?>
   521 <?php elseif ( 'update-selected' == $action ) : ?>
   442 	<div id="message" class="updated notice is-dismissible"><p><?php _e('No out of date plugins were selected.'); ?></p></div>
   522 	<div id="message" class="updated notice is-dismissible"><p><?php _e('All selected plugins are up to date.'); ?></p></div>
   443 <?php endif; ?>
   523 <?php endif; ?>
   444 
   524 
   445 <div class="wrap">
   525 <div class="wrap">
   446 <h2><?php echo esc_html( $title );
   526 <h1 class="wp-heading-inline"><?php
       
   527 echo esc_html( $title );
       
   528 ?></h1>
       
   529 
       
   530 <?php
   447 if ( ( ! is_multisite() || is_network_admin() ) && current_user_can('install_plugins') ) { ?>
   531 if ( ( ! is_multisite() || is_network_admin() ) && current_user_can('install_plugins') ) { ?>
   448  <a href="<?php echo self_admin_url( 'plugin-install.php' ); ?>" class="add-new-h2"><?php echo esc_html_x('Add New', 'plugin'); ?></a>
   532 	<a href="<?php echo self_admin_url( 'plugin-install.php' ); ?>" class="page-title-action"><?php echo esc_html_x( 'Add New', 'plugin' ); ?></a>
   449 <?php }
   533 <?php
   450 if ( $s )
   534 }
   451 	printf( '<span class="subtitle">' . __('Search results for &#8220;%s&#8221;') . '</span>', esc_html( $s ) ); ?>
   535 
   452 </h2>
   536 if ( strlen( $s ) ) {
       
   537 	/* translators: %s: search keywords */
       
   538 	printf( '<span class="subtitle">' . __( 'Search results for &#8220;%s&#8221;' ) . '</span>', esc_html( urldecode( $s ) ) );
       
   539 }
       
   540 ?>
       
   541 
       
   542 <hr class="wp-header-end">
   453 
   543 
   454 <?php
   544 <?php
   455 /**
   545 /**
   456  * Fires before the plugins list table is rendered.
   546  * Fires before the plugins list table is rendered.
   457  *
   547  *
   467 do_action( 'pre_current_active_plugins', $plugins['all'] );
   557 do_action( 'pre_current_active_plugins', $plugins['all'] );
   468 ?>
   558 ?>
   469 
   559 
   470 <?php $wp_list_table->views(); ?>
   560 <?php $wp_list_table->views(); ?>
   471 
   561 
   472 <form method="get">
   562 <form class="search-form search-plugins" method="get">
   473 <?php $wp_list_table->search_box( __( 'Search Installed Plugins' ), 'plugin' ); ?>
   563 <?php $wp_list_table->search_box( __( 'Search Installed Plugins' ), 'plugin' ); ?>
   474 </form>
   564 </form>
   475 
   565 
   476 <form method="post" id="bulk-action-form">
   566 <form method="post" id="bulk-action-form">
   477 
   567 
   479 <input type="hidden" name="paged" value="<?php echo esc_attr($page) ?>" />
   569 <input type="hidden" name="paged" value="<?php echo esc_attr($page) ?>" />
   480 
   570 
   481 <?php $wp_list_table->display(); ?>
   571 <?php $wp_list_table->display(); ?>
   482 </form>
   572 </form>
   483 
   573 
       
   574 	<span class="spinner"></span>
   484 </div>
   575 </div>
   485 
   576 
   486 <?php
   577 <?php
   487 wp_print_request_filesystem_credentials_modal();
   578 wp_print_request_filesystem_credentials_modal();
       
   579 wp_print_admin_notice_templates();
       
   580 wp_print_update_row_templates();
   488 
   581 
   489 include(ABSPATH . 'wp-admin/admin-footer.php');
   582 include(ABSPATH . 'wp-admin/admin-footer.php');