WordPress 4.0
[autoinstalls/wordpress.git] / wp-admin / plugins.php
1 <?php
2 /**
3  * Plugins administration panel.
4  *
5  * @package WordPress
6  * @subpackage Administration
7  */
8
9 /** WordPress Administration Bootstrap */
10 require_once( dirname( __FILE__ ) . '/admin.php' );
11
12 if ( ! current_user_can('activate_plugins') )
13         wp_die( __( 'You do not have sufficient permissions to manage plugins for this site.' ) );
14
15 $wp_list_table = _get_list_table('WP_Plugins_List_Table');
16 $pagenum = $wp_list_table->get_pagenum();
17
18 $action = $wp_list_table->current_action();
19
20 $plugin = isset($_REQUEST['plugin']) ? $_REQUEST['plugin'] : '';
21 $s = isset($_REQUEST['s']) ? urlencode($_REQUEST['s']) : '';
22
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']);
25
26 if ( $action ) {
27
28         switch ( $action ) {
29                 case 'activate':
30                         if ( ! current_user_can('activate_plugins') )
31                                 wp_die(__('You do not have sufficient permissions to activate plugins for this site.'));
32
33                         if ( is_multisite() && ! is_network_admin() && is_network_only_plugin( $plugin ) ) {
34                                 wp_redirect( self_admin_url("plugins.php?plugin_status=$status&paged=$page&s=$s") );
35                                 exit;
36                         }
37
38                         check_admin_referer('activate-plugin_' . $plugin);
39
40                         $result = activate_plugin($plugin, self_admin_url('plugins.php?error=true&plugin=' . $plugin), is_network_admin() );
41                         if ( is_wp_error( $result ) ) {
42                                 if ( 'unexpected_output' == $result->get_error_code() ) {
43                                         $redirect = self_admin_url('plugins.php?error=true&charsout=' . strlen($result->get_error_data()) . '&plugin=' . $plugin . "&plugin_status=$status&paged=$page&s=$s");
44                                         wp_redirect(add_query_arg('_error_nonce', wp_create_nonce('plugin-activation-error_' . $plugin), $redirect));
45                                         exit;
46                                 } else {
47                                         wp_die($result);
48                                 }
49                         }
50
51                         if ( ! is_network_admin() ) {
52                                 $recent = (array) get_option( 'recently_activated' );
53                                 unset( $recent[ $plugin ] );
54                                 update_option( 'recently_activated', $recent );
55                         }
56
57                         if ( isset($_GET['from']) && 'import' == $_GET['from'] ) {
58                                 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
59                         } else {
60                                 wp_redirect( self_admin_url("plugins.php?activate=true&plugin_status=$status&paged=$page&s=$s") ); // overrides the ?error=true one above
61                         }
62                         exit;
63
64                 case 'activate-selected':
65                         if ( ! current_user_can('activate_plugins') )
66                                 wp_die(__('You do not have sufficient permissions to activate plugins for this site.'));
67
68                         check_admin_referer('bulk-plugins');
69
70                         $plugins = isset( $_POST['checked'] ) ? (array) $_POST['checked'] : array();
71
72                         if ( is_network_admin() ) {
73                                 foreach ( $plugins as $i => $plugin ) {
74                                         // Only activate plugins which are not already network activated.
75                                         if ( is_plugin_active_for_network( $plugin ) ) {
76                                                 unset( $plugins[ $i ] );
77                                         }
78                                 }
79                         } else {
80                                 foreach ( $plugins as $i => $plugin ) {
81                                         // Only activate plugins which are not already active and are not network-only when on Multisite.
82                                         if ( is_plugin_active( $plugin ) || ( is_multisite() && is_network_only_plugin( $plugin ) ) ) {
83                                                 unset( $plugins[ $i ] );
84                                         }
85                                 }
86                         }
87
88                         if ( empty($plugins) ) {
89                                 wp_redirect( self_admin_url("plugins.php?plugin_status=$status&paged=$page&s=$s") );
90                                 exit;
91                         }
92
93                         activate_plugins($plugins, self_admin_url('plugins.php?error=true'), is_network_admin() );
94
95                         if ( ! is_network_admin() ) {
96                                 $recent = (array) get_option('recently_activated' );
97                                 foreach ( $plugins as $plugin )
98                                         unset( $recent[ $plugin ] );
99                                 update_option( 'recently_activated', $recent );
100                         }
101
102                         wp_redirect( self_admin_url("plugins.php?activate-multi=true&plugin_status=$status&paged=$page&s=$s") );
103                         exit;
104
105                 case 'update-selected' :
106
107                         check_admin_referer( 'bulk-plugins' );
108
109                         if ( isset( $_GET['plugins'] ) )
110                                 $plugins = explode( ',', $_GET['plugins'] );
111                         elseif ( isset( $_POST['checked'] ) )
112                                 $plugins = (array) $_POST['checked'];
113                         else
114                                 $plugins = array();
115
116                         $title = __( 'Update Plugins' );
117                         $parent_file = 'plugins.php';
118
119                         wp_enqueue_script( 'updates' );
120                         require_once(ABSPATH . 'wp-admin/admin-header.php');
121
122                         echo '<div class="wrap">';
123                         echo '<h2>' . esc_html( $title ) . '</h2>';
124
125                         $url = self_admin_url('update.php?action=update-selected&amp;plugins=' . urlencode( join(',', $plugins) ));
126                         $url = wp_nonce_url($url, 'bulk-update-plugins');
127
128                         echo "<iframe src='$url' style='width: 100%; height:100%; min-height:850px;'></iframe>";
129                         echo '</div>';
130                         require_once(ABSPATH . 'wp-admin/admin-footer.php');
131                         exit;
132
133                 case 'error_scrape':
134                         if ( ! current_user_can('activate_plugins') )
135                                 wp_die(__('You do not have sufficient permissions to activate plugins for this site.'));
136
137                         check_admin_referer('plugin-activation-error_' . $plugin);
138
139                         $valid = validate_plugin($plugin);
140                         if ( is_wp_error($valid) )
141                                 wp_die($valid);
142
143                         if ( ! WP_DEBUG ) {
144                                 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 );
145                         }
146
147                         @ini_set('display_errors', true); //Ensure that Fatal errors are displayed.
148                         // Go back to "sandbox" scope so we get the same errors as before
149                         function plugin_sandbox_scrape( $plugin ) {
150                                 wp_register_plugin_realpath( WP_PLUGIN_DIR . '/' . $plugin );
151                                 include( WP_PLUGIN_DIR . '/' . $plugin );
152                         }
153                         plugin_sandbox_scrape( $plugin );
154                         /** This action is documented in wp-admin/includes/plugins.php */
155                         do_action( "activate_{$plugin}" );
156                         exit;
157
158                 case 'deactivate':
159                         if ( ! current_user_can('activate_plugins') )
160                                 wp_die(__('You do not have sufficient permissions to deactivate plugins for this site.'));
161
162                         check_admin_referer('deactivate-plugin_' . $plugin);
163
164                         if ( ! is_network_admin() && is_plugin_active_for_network( $plugin ) ) {
165                                 wp_redirect( self_admin_url("plugins.php?plugin_status=$status&paged=$page&s=$s") );
166                                 exit;
167                         }
168
169                         deactivate_plugins( $plugin, false, is_network_admin() );
170                         if ( ! is_network_admin() )
171                                 update_option( 'recently_activated', array( $plugin => time() ) + (array) get_option( 'recently_activated' ) );
172                         if ( headers_sent() )
173                                 echo "<meta http-equiv='refresh' content='" . esc_attr( "0;url=plugins.php?deactivate=true&plugin_status=$status&paged=$page&s=$s" ) . "' />";
174                         else
175                                 wp_redirect( self_admin_url("plugins.php?deactivate=true&plugin_status=$status&paged=$page&s=$s") );
176                         exit;
177
178                 case 'deactivate-selected':
179                         if ( ! current_user_can('activate_plugins') )
180                                 wp_die(__('You do not have sufficient permissions to deactivate plugins for this site.'));
181
182                         check_admin_referer('bulk-plugins');
183
184                         $plugins = isset( $_POST['checked'] ) ? (array) $_POST['checked'] : array();
185                         // Do not deactivate plugins which are already deactivated.
186                         if ( is_network_admin() ) {
187                                 $plugins = array_filter( $plugins, 'is_plugin_active_for_network' );
188                         } else {
189                                 $plugins = array_filter( $plugins, 'is_plugin_active' );
190                                 $plugins = array_diff( $plugins, array_filter( $plugins, 'is_plugin_active_for_network' ) );
191                         }
192                         if ( empty($plugins) ) {
193                                 wp_redirect( self_admin_url("plugins.php?plugin_status=$status&paged=$page&s=$s") );
194                                 exit;
195                         }
196
197                         deactivate_plugins( $plugins, false, is_network_admin() );
198
199                         if ( ! is_network_admin() ) {
200                                 $deactivated = array();
201                                 foreach ( $plugins as $plugin )
202                                         $deactivated[ $plugin ] = time();
203                                 update_option( 'recently_activated', $deactivated + (array) get_option( 'recently_activated' ) );
204                         }
205
206                         wp_redirect( self_admin_url("plugins.php?deactivate-multi=true&plugin_status=$status&paged=$page&s=$s") );
207                         exit;
208
209                 case 'delete-selected':
210                         if ( ! current_user_can('delete_plugins') )
211                                 wp_die(__('You do not have sufficient permissions to delete plugins for this site.'));
212
213                         check_admin_referer('bulk-plugins');
214
215                         //$_POST = from the plugin form; $_GET = from the FTP details screen.
216                         $plugins = isset( $_REQUEST['checked'] ) ? (array) $_REQUEST['checked'] : array();
217                         if ( empty( $plugins ) ) {
218                                 wp_redirect( self_admin_url("plugins.php?plugin_status=$status&paged=$page&s=$s") );
219                                 exit;
220                         }
221
222                         $plugins = array_filter($plugins, 'is_plugin_inactive'); // Do not allow to delete Activated plugins.
223                         if ( empty( $plugins ) ) {
224                                 wp_redirect( self_admin_url( "plugins.php?error=true&main=true&plugin_status=$status&paged=$page&s=$s" ) );
225                                 exit;
226                         }
227
228                         include(ABSPATH . 'wp-admin/update.php');
229
230                         $parent_file = 'plugins.php';
231
232                         if ( ! isset($_REQUEST['verify-delete']) ) {
233                                 wp_enqueue_script('jquery');
234                                 require_once(ABSPATH . 'wp-admin/admin-header.php');
235                                 ?>
236                         <div class="wrap">
237                                 <?php
238                                         $files_to_delete = $plugin_info = array();
239                                         $have_non_network_plugins = false;
240                                         foreach ( (array) $plugins as $plugin ) {
241                                                 if ( '.' == dirname($plugin) ) {
242                                                         $files_to_delete[] = WP_PLUGIN_DIR . '/' . $plugin;
243                                                         if( $data = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin) ) {
244                                                                 $plugin_info[ $plugin ] = $data;
245                                                                 $plugin_info[ $plugin ]['is_uninstallable'] = is_uninstallable_plugin( $plugin );
246                                                                 if ( ! $plugin_info[ $plugin ]['Network'] )
247                                                                         $have_non_network_plugins = true;
248                                                         }
249                                                 } else {
250                                                         // Locate all the files in that folder
251                                                         $files = list_files( WP_PLUGIN_DIR . '/' . dirname($plugin) );
252                                                         if ( $files ) {
253                                                                 $files_to_delete = array_merge($files_to_delete, $files);
254                                                         }
255                                                         // Get plugins list from that folder
256                                                         if ( $folder_plugins = get_plugins( '/' . dirname($plugin)) ) {
257                                                                 foreach( $folder_plugins as $plugin_file => $data ) {
258                                                                         $plugin_info[ $plugin_file ] = _get_plugin_data_markup_translate( $plugin_file, $data );
259                                                                         $plugin_info[ $plugin_file ]['is_uninstallable'] = is_uninstallable_plugin( $plugin );
260                                                                         if ( ! $plugin_info[ $plugin_file ]['Network'] )
261                                                                                 $have_non_network_plugins = true;
262                                                                 }
263                                                         }
264                                                 }
265                                         }
266                                         $plugins_to_delete = count( $plugin_info );
267                                         echo '<h2>' . _n( 'Delete Plugin', 'Delete Plugins', $plugins_to_delete ) . '</h2>';
268                                 ?>
269                                 <?php if ( $have_non_network_plugins && is_network_admin() ) : ?>
270                                 <div class="error"><p><strong><?php _e( 'Caution:' ); ?></strong> <?php echo _n( 'This plugin may be active on other sites in the network.', 'These plugins may be active on other sites in the network.', $plugins_to_delete ); ?></p></div>
271                                 <?php endif; ?>
272                                 <p><?php echo _n( 'You are about to remove the following plugin:', 'You are about to remove the following plugins:', $plugins_to_delete ); ?></p>
273                                         <ul class="ul-disc">
274                                                 <?php
275                                                 $data_to_delete = false;
276                                                 foreach ( $plugin_info as $plugin ) {
277                                                         if ( $plugin['is_uninstallable'] ) {
278                                                                 /* translators: 1: plugin name, 2: plugin author */
279                                                                 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>';
280                                                                 $data_to_delete = true;
281                                                         } else {
282                                                                 /* translators: 1: plugin name, 2: plugin author */
283                                                                 echo '<li>', sprintf( __('<strong>%1$s</strong> by <em>%2$s</em>' ), esc_html($plugin['Name']), esc_html($plugin['AuthorName']) ), '</li>';
284                                                         }
285                                                 }
286                                                 ?>
287                                         </ul>
288                                 <p><?php
289                                 if ( $data_to_delete )
290                                         _e('Are you sure you wish to delete these files and data?');
291                                 else
292                                         _e('Are you sure you wish to delete these files?');
293                                 ?></p>
294                                 <form method="post" action="<?php echo esc_url($_SERVER['REQUEST_URI']); ?>" style="display:inline;">
295                                         <input type="hidden" name="verify-delete" value="1" />
296                                         <input type="hidden" name="action" value="delete-selected" />
297                                         <?php
298                                                 foreach ( (array) $plugins as $plugin )
299                                                         echo '<input type="hidden" name="checked[]" value="' . esc_attr($plugin) . '" />';
300                                         ?>
301                                         <?php wp_nonce_field('bulk-plugins') ?>
302                                         <?php submit_button( $data_to_delete ? __( 'Yes, Delete these files and data' ) : __( 'Yes, Delete these files' ), 'button', 'submit', false ); ?>
303                                 </form>
304                                 <form method="post" action="<?php echo esc_url(wp_get_referer()); ?>" style="display:inline;">
305                                         <?php submit_button( __( 'No, Return me to the plugin list' ), 'button', 'submit', false ); ?>
306                                 </form>
307
308                                 <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>
309                                 <div id="files-list" style="display:none;">
310                                         <ul class="code">
311                                         <?php
312                                                 foreach ( (array)$files_to_delete as $file )
313                                                         echo '<li>' . esc_html(str_replace(WP_PLUGIN_DIR, '', $file)) . '</li>';
314                                         ?>
315                                         </ul>
316                                 </div>
317                         </div>
318                                 <?php
319                                 require_once(ABSPATH . 'wp-admin/admin-footer.php');
320                                 exit;
321                         } //Endif verify-delete
322                         $delete_result = delete_plugins($plugins);
323
324                         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
325                         wp_redirect( self_admin_url("plugins.php?deleted=true&plugin_status=$status&paged=$page&s=$s") );
326                         exit;
327
328                 case 'clear-recent-list':
329                         if ( ! is_network_admin() )
330                                 update_option( 'recently_activated', array() );
331                         break;
332         }
333 }
334
335 $wp_list_table->prepare_items();
336
337 wp_enqueue_script('plugin-install');
338 add_thickbox();
339
340 add_screen_option( 'per_page', array('label' => _x( 'Plugins', 'plugins per page (screen options)' ), 'default' => 999 ) );
341
342 get_current_screen()->add_help_tab( array(
343 'id'            => 'overview',
344 'title'         => __('Overview'),
345 'content'       =>
346         '<p>' . __('Plugins extend and expand the functionality of WordPress. Once a plugin is installed, you may activate it or deactivate it here.') . '</p>' .
347         '<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>'
348 ) );
349 get_current_screen()->add_help_tab( array(
350 'id'            => 'compatibility-problems',
351 'title'         => __('Troubleshooting'),
352 'content'       =>
353         '<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>' .
354         '<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>'
355 ) );
356
357 get_current_screen()->set_help_sidebar(
358         '<p><strong>' . __('For more information:') . '</strong></p>' .
359         '<p>' . __('<a href="http://codex.wordpress.org/Managing_Plugins#Plugin_Management" target="_blank">Documentation on Managing Plugins</a>') . '</p>' .
360         '<p>' . __('<a href="https://wordpress.org/support/" target="_blank">Support Forums</a>') . '</p>'
361 );
362
363 $title = __('Plugins');
364 $parent_file = 'plugins.php';
365
366 require_once(ABSPATH . 'wp-admin/admin-header.php');
367
368 $invalid = validate_active_plugins();
369 if ( !empty($invalid) )
370         foreach ( $invalid as $plugin_file => $error )
371                 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>';
372 ?>
373
374 <?php if ( isset($_GET['error']) ) :
375
376         if ( isset( $_GET['main'] ) )
377                 $errmsg = __( 'You cannot delete a plugin while it is active on the main site.' );
378         elseif ( isset($_GET['charsout']) )
379                 $errmsg = sprintf(__('The plugin generated %d characters of <strong>unexpected output</strong> during activation. If you notice &#8220;headers already sent&#8221; messages, problems with syndication feeds or other issues, try deactivating or removing this plugin.'), $_GET['charsout']);
380         else
381                 $errmsg = __('Plugin could not be activated because it triggered a <strong>fatal error</strong>.');
382         ?>
383         <div id="message" class="error"><p><?php echo $errmsg; ?></p>
384         <?php
385                 if ( !isset( $_GET['main'] ) && !isset($_GET['charsout']) && wp_verify_nonce($_GET['_error_nonce'], 'plugin-activation-error_' . $plugin) ) { ?>
386         <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>
387         <?php
388                 }
389         ?>
390         </div>
391 <?php elseif ( isset($_GET['deleted']) ) :
392                 $delete_result = get_transient( 'plugins_delete_result_' . $user_ID );
393                 // Delete it once we're done.
394                 delete_transient( 'plugins_delete_result_' . $user_ID );
395
396                 if ( is_wp_error($delete_result) ) : ?>
397                 <div id="message" class="error"><p><?php printf( __('Plugin could not be deleted due to an error: %s'), $delete_result->get_error_message() ); ?></p></div>
398                 <?php else : ?>
399                 <div id="message" class="updated"><p><?php _e('The selected plugins have been <strong>deleted</strong>.'); ?></p></div>
400                 <?php endif; ?>
401 <?php elseif ( isset($_GET['activate']) ) : ?>
402         <div id="message" class="updated"><p><?php _e('Plugin <strong>activated</strong>.') ?></p></div>
403 <?php elseif (isset($_GET['activate-multi'])) : ?>
404         <div id="message" class="updated"><p><?php _e('Selected plugins <strong>activated</strong>.'); ?></p></div>
405 <?php elseif ( isset($_GET['deactivate']) ) : ?>
406         <div id="message" class="updated"><p><?php _e('Plugin <strong>deactivated</strong>.') ?></p></div>
407 <?php elseif (isset($_GET['deactivate-multi'])) : ?>
408         <div id="message" class="updated"><p><?php _e('Selected plugins <strong>deactivated</strong>.'); ?></p></div>
409 <?php elseif ( 'update-selected' == $action ) : ?>
410         <div id="message" class="updated"><p><?php _e('No out of date plugins were selected.'); ?></p></div>
411 <?php endif; ?>
412
413 <div class="wrap">
414 <h2><?php echo esc_html( $title );
415 if ( ( ! is_multisite() || is_network_admin() ) && current_user_can('install_plugins') ) { ?>
416  <a href="<?php echo self_admin_url( 'plugin-install.php' ); ?>" class="add-new-h2"><?php echo esc_html_x('Add New', 'plugin'); ?></a>
417 <?php }
418 if ( $s )
419         printf( '<span class="subtitle">' . __('Search results for &#8220;%s&#8221;') . '</span>', esc_html( $s ) ); ?>
420 </h2>
421
422 <?php
423 /**
424  * Fires before the plugins list table is rendered.
425  *
426  * This hook also fires before the plugins list table is rendered in the Network Admin.
427  *
428  * Please note: The 'active' portion of the hook name does not refer to whether the current
429  * view is for active plugins, but rather all plugins actively-installed.
430  *
431  * @since 3.0.0
432  *
433  * @param array $plugins_all An array containing all installed plugins.
434  */
435 do_action( 'pre_current_active_plugins', $plugins['all'] );
436 ?>
437
438 <?php $wp_list_table->views(); ?>
439
440 <form method="get" action="">
441 <?php $wp_list_table->search_box( __( 'Search Installed Plugins' ), 'plugin' ); ?>
442 </form>
443
444 <form method="post" action="">
445
446 <input type="hidden" name="plugin_status" value="<?php echo esc_attr($status) ?>" />
447 <input type="hidden" name="paged" value="<?php echo esc_attr($page) ?>" />
448
449 <?php $wp_list_table->display(); ?>
450 </form>
451
452 </div>
453
454 <?php
455 include(ABSPATH . 'wp-admin/admin-footer.php');