Wordpress 2.7.1
[autoinstalls/wordpress.git] / wp-admin / includes / plugin-install.php
1 <?php
2 /**
3  * WordPress Plugin Install Administration API
4  *
5  * @package WordPress
6  * @subpackage Administration
7  */
8
9 /**
10  * Retrieve plugin installer pages from WordPress Plugins API.
11  *
12  * It is possible for a plugin to override the Plugin API result with three
13  * filters. Assume this is for plugins, which can extend on the Plugin Info to
14  * offer more choices. This is very powerful and must be used with care, when
15  * overridding the filters.
16  *
17  * The first filter, 'plugins_api_args', is for the args and gives the action as
18  * the second parameter. The hook for 'plugins_api_args' must ensure that an
19  * object is returned.
20  *
21  * The second filter, 'plugins_api', is the result that would be returned.
22  *
23  * @since 2.7.0
24  *
25  * @param string $action
26  * @param array|object $args Optional. Arguments to serialize for the Plugin Info API.
27  * @return mixed
28  */
29 function plugins_api($action, $args = null) {
30
31         if( is_array($args) )
32                 $args = (object)$args;
33
34         if ( !isset($args->per_page) )
35                 $args->per_page = 24;
36
37         $args = apply_filters('plugins_api_args', $args, $action); //NOTE: Ensure that an object is returned via this filter.
38         $res = apply_filters('plugins_api', false, $action, $args); //NOTE: Allows a plugin to completely override the builtin WordPress.org API.
39
40         if ( ! $res ) {
41                 $request = wp_remote_post('http://api.wordpress.org/plugins/info/1.0/', array( 'body' => array('action' => $action, 'request' => serialize($args))) );
42                 if ( is_wp_error($request) ) {
43                         $res = new WP_Error('plugins_api_failed', __('An Unexpected HTTP Error occured during the API request.</p> <p><a href="?" onclick="document.location.reload(); return false;">Try again</a>'), $request->get_error_message() );
44                 } else {
45                         $res = unserialize($request['body']);
46                         if ( ! $res )
47                                 $res = new WP_Error('plugins_api_failed', __('An unknown error occured'), $request['body']);
48                 }
49         }
50
51         return apply_filters('plugins_api_result', $res, $action, $args);
52 }
53
54 /**
55  * Retrieve popular WordPress plugin tags.
56  *
57  * @since 2.7.0
58  *
59  * @param array $args
60  * @return array
61  */
62 function install_popular_tags( $args = array() ) {
63         if ( ! ($cache = wp_cache_get('popular_tags', 'api')) && ! ($cache = get_option('wporg_popular_tags')) )
64                 add_option('wporg_popular_tags', array(), '', 'no'); ///No autoload.
65
66         if ( $cache && $cache->timeout + 3 * 60 * 60 > time() )
67                 return $cache->cached;
68
69         $tags = plugins_api('hot_tags', $args);
70
71         if ( is_wp_error($tags) )
72                 return $tags;
73
74         $cache = (object) array('timeout' => time(), 'cached' => $tags);
75
76         update_option('wporg_popular_tags', $cache);
77         wp_cache_set('popular_tags', $cache, 'api');
78
79         return $tags;
80 }
81 add_action('install_plugins_search', 'install_search', 10, 1);
82
83 /**
84  * Display search results and display as tag cloud.
85  *
86  * @since 2.7.0
87  *
88  * @param string $page
89  */
90 function install_search($page) {
91         $type = isset($_REQUEST['type']) ? stripslashes( $_REQUEST['type'] ) : '';
92         $term = isset($_REQUEST['s']) ? stripslashes( $_REQUEST['s'] ) : '';
93
94         $args = array();
95
96         switch( $type ){
97                 case 'tag':
98                         $args['tag'] = sanitize_title_with_dashes($term);
99                         break;
100                 case 'term':
101                         $args['search'] = $term;
102                         break;
103                 case 'author':
104                         $args['author'] = $term;
105                         break;
106         }
107
108         $args['page'] = $page;
109
110         $api = plugins_api('query_plugins', $args);
111
112         if ( is_wp_error($api) )
113                 wp_die($api);
114
115         add_action('install_plugins_table_header', 'install_search_form');
116
117         display_plugins_table($api->plugins, $api->info['page'], $api->info['pages']);
118
119         return;
120 }
121
122 add_action('install_plugins_dashboard', 'install_dashboard');
123 function install_dashboard() {
124         ?>
125         <p><?php _e('Plugins extend and expand the functionality of WordPress. You may automatically install plugins from the <a href="http://wordpress.org/extend/plugins/">WordPress Plugin Directory</a> or upload a plugin in .zip format via this page.') ?></p>
126
127         <h4><?php _e('Search') ?></h4>
128         <?php install_search_form('<a href="' . add_query_arg('show-help', !isset($_REQUEST['show-help'])) .'" onclick="jQuery(\'#search-help\').toggle(); return false;">' . __('[need help?]') . '</a>') ?>
129         <div id="search-help" style="display: <?php echo isset($_REQUEST['show-help']) ? 'block' : 'none'; ?>;">
130         <p>     <?php _e('You may search based on 3 criteria:') ?><br />
131                 <?php _e('<strong>Term:</strong> Searches plugins names and descriptions for the specified term') ?><br />
132                 <?php _e('<strong>Tag:</strong> Searches for plugins tagged as such') ?><br />
133                 <?php _e('<strong>Author:</strong> Searches for plugins created by the Author, or which the Author contributed to.') ?></p>
134         </div>
135
136         <h4><?php _e('Install a plugin in .zip format') ?></h4>
137         <p><?php _e('If you have a plugin in a .zip format, You may install it by uploading it here.') ?></p>
138         <form method="post" enctype="multipart/form-data" action="<?php echo admin_url('plugin-install.php?tab=upload') ?>">
139                 <?php wp_nonce_field( 'plugin-upload') ?>
140                 <input type="file" name="pluginzip" />
141                 <input type="submit" class="button" value="<?php _e('Install Now') ?>" />
142         </form>
143
144         <h4><?php _e('Popular tags') ?></h4>
145         <p><?php _e('You may also browse based on the most popular tags in the Plugin Directory:') ?></p>
146         <?php
147
148         $api_tags = install_popular_tags();
149
150         //Set up the tags in a way which can be interprated by wp_generate_tag_cloud()
151         $tags = array();
152         foreach ( (array)$api_tags as $tag )
153                 $tags[ $tag['name'] ] = (object) array(
154                                                                 'link' => clean_url( admin_url('plugin-install.php?tab=search&type=tag&s=' . urlencode($tag['name'])) ),
155                                                                 'name' => $tag['name'],
156                                                                 'id' => sanitize_title_with_dashes($tag['name']),
157                                                                 'count' => $tag['count'] );
158         echo wp_generate_tag_cloud($tags, array( 'single_text' => __('%d plugin'), 'multiple_text' => __('%d plugins') ) );
159 }
160
161 /**
162  * Display search form for searching plugins.
163  *
164  * @since 2.7.0
165  */
166 function install_search_form(){
167         $type = isset($_REQUEST['type']) ? stripslashes( $_REQUEST['type'] ) : '';
168         $term = isset($_REQUEST['s']) ? stripslashes( $_REQUEST['s'] ) : '';
169
170         ?><form id="search-plugins" method="post" action="<?php echo admin_url('plugin-install.php?tab=search') ?>">
171                 <select name="type" id="typeselector">
172                         <option value="term"<?php selected('term', $type) ?>><?php _e('Term') ?></option>
173                         <option value="author"<?php selected('author', $type) ?>><?php _e('Author') ?></option>
174                         <option value="tag"<?php selected('tag', $type) ?>><?php _e('Tag') ?></option>
175                 </select>
176                 <input type="text" name="s" id="search-field" value="<?php echo attribute_escape($term) ?>" />
177                 <input type="submit" name="search" value="<?php echo attribute_escape(__('Search')) ?>" class="button" />
178         </form><?php
179 }
180
181 add_action('install_plugins_featured', 'install_featured', 10, 1);
182 /**
183  * Display featured plugins.
184  *
185  * @since 2.7.0
186  *
187  * @param string $page
188  */
189 function install_featured($page = 1) {
190         $args = array('browse' => 'featured', 'page' => $page);
191         $api = plugins_api('query_plugins', $args);
192         if ( is_wp_error($api) )
193                 wp_die($api);
194         display_plugins_table($api->plugins, $api->info['page'], $api->info['pages']);
195 }
196
197 add_action('install_plugins_popular', 'install_popular', 10, 1);
198 /**
199  * Display popular plugins.
200  *
201  * @since 2.7.0
202  *
203  * @param string $page
204  */
205 function install_popular($page = 1) {
206         $args = array('browse' => 'popular', 'page' => $page);
207         $api = plugins_api('query_plugins', $args);
208         display_plugins_table($api->plugins, $api->info['page'], $api->info['pages']);
209 }
210
211 add_action('install_plugins_new', 'install_new', 10, 1);
212 /**
213  * Display new plugins.
214  *
215  * @since 2.7.0
216  *
217  * @param string $page
218  */
219 function install_new($page = 1) {
220         $args = array('browse' => 'new', 'page' => $page);
221         $api = plugins_api('query_plugins', $args);
222         if ( is_wp_error($api) )
223                 wp_die($api);
224         display_plugins_table($api->plugins, $api->info['page'], $api->info['pages']);
225 }
226 add_action('install_plugins_updated', 'install_updated', 10, 1);
227
228
229 /**
230  * Display recently updated plugins.
231  *
232  * @since 2.7.0
233  *
234  * @param string $page
235  */
236 function install_updated($page = 1) {
237         $args = array('browse' => 'updated', 'page' => $page);
238         $api = plugins_api('query_plugins', $args);
239         display_plugins_table($api->plugins, $api->info['page'], $api->info['pages']);
240 }
241
242 /**
243  * Display plugin content based on plugin list.
244  *
245  * @since 2.7.0
246  *
247  * @param array $plugins List of plugins.
248  * @param string $page
249  * @param int $totalpages Number of pages.
250  */
251 function display_plugins_table($plugins, $page = 1, $totalpages = 1){
252         $type = isset($_REQUEST['type']) ? stripslashes( $_REQUEST['type'] ) : '';
253         $term = isset($_REQUEST['s']) ? stripslashes( $_REQUEST['s'] ) : '';
254
255         $plugins_allowedtags = array('a' => array('href' => array(),'title' => array(), 'target' => array()),
256                                                                 'abbr' => array('title' => array()),'acronym' => array('title' => array()),
257                                                                 'code' => array(), 'pre' => array(), 'em' => array(),'strong' => array());
258
259 ?>
260         <div class="tablenav">
261                 <div class="alignleft actions">
262                 <?php do_action('install_plugins_table_header'); ?>
263                 </div>
264                 <?php
265                         $url = clean_url($_SERVER['REQUEST_URI']);
266                         if ( ! empty($term) )
267                                 $url = add_query_arg('s', $term, $url);
268                         if ( ! empty($type) )
269                                 $url = add_query_arg('type', $type, $url);
270
271                         $page_links = paginate_links( array(
272                                 'base' => add_query_arg('paged', '%#%', $url),
273                                 'format' => '',
274                                 'prev_text' => __('&laquo;'),
275                                 'next_text' => __('&raquo;'),
276                                 'total' => $totalpages,
277                                 'current' => $page
278                         ));
279
280                         if ( $page_links )
281                                 echo "\t\t<div class='tablenav-pages'>$page_links</div>";
282 ?>
283                 <br class="clear" />
284         </div>
285         <table class="widefat" id="install-plugins" cellspacing="0">
286                 <thead>
287                         <tr>
288                                 <th scope="col" class="name"><?php _e('Name'); ?></th>
289                                 <th scope="col" class="num"><?php _e('Version'); ?></th>
290                                 <th scope="col" class="num"><?php _e('Rating'); ?></th>
291                                 <th scope="col" class="desc"><?php _e('Description'); ?></th>
292                                 <th scope="col" class="action-links"><?php _e('Actions'); ?></th>
293                         </tr>
294                 </thead>
295
296                 <tfoot>
297                         <tr>
298                                 <th scope="col" class="name"><?php _e('Name'); ?></th>
299                                 <th scope="col" class="num"><?php _e('Version'); ?></th>
300                                 <th scope="col" class="num"><?php _e('Rating'); ?></th>
301                                 <th scope="col" class="desc"><?php _e('Description'); ?></th>
302                                 <th scope="col" class="action-links"><?php _e('Actions'); ?></th>
303                         </tr>
304                 </tfoot>
305
306                 <tbody class="plugins">
307                 <?php
308                         if( empty($plugins) )
309                                 echo '<tr><td colspan="5">', __('No plugins match your request.'), '</td></tr>';
310
311                         foreach( (array) $plugins as $plugin ){
312                                 if ( is_object($plugin) )
313                                         $plugin = (array) $plugin;
314
315                                 $title = wp_kses($plugin['name'], $plugins_allowedtags);
316                                 $description = wp_kses($plugin['description'], $plugins_allowedtags);
317                                 $version = wp_kses($plugin['version'], $plugins_allowedtags);
318
319                                 $name = strip_tags($title . ' ' . $version);
320
321                                 $author = $plugin['author'];
322                                 if( ! empty($plugin['author']) )
323                                         $author = ' <cite>' . sprintf( __('By %s'), $author ) . '.</cite>';
324
325                                 $author = wp_kses($author, $plugins_allowedtags);
326
327                                 if( isset($plugin['homepage']) )
328                                         $title = '<a target="_blank" href="' . attribute_escape($plugin['homepage']) . '">' . $title . '</a>';
329
330                                 $action_links = array();
331                                 $action_links[] = '<a href="' . admin_url('plugin-install.php?tab=plugin-information&amp;plugin=' . $plugin['slug'] .
332                                                                         '&amp;TB_iframe=true&amp;width=600&amp;height=800') . '" class="thickbox onclick" title="' .
333                                                                         attribute_escape($name) . '">' . __('Install') . '</a>';
334
335                                 $action_links = apply_filters('plugin_install_action_links', $action_links, $plugin);
336                         ?>
337                         <tr>
338                                 <td class="name"><?php echo $title; ?></td>
339                                 <td class="vers"><?php echo $version; ?></td>
340                                 <td class="vers">
341                                         <div class="star-holder" title="<?php printf(__ngettext('(based on %s rating)', '(based on %s ratings)', $plugin['num_ratings']), number_format_i18n($plugin['num_ratings'])) ?>">
342                                                 <div class="star star-rating" style="width: <?php echo attribute_escape($plugin['rating']) ?>px"></div>
343                                                 <div class="star star5"><img src="<?php echo admin_url('images/star.gif'); ?>" alt="<?php _e('5 stars') ?>" /></div>
344                                                 <div class="star star4"><img src="<?php echo admin_url('images/star.gif'); ?>" alt="<?php _e('4 stars') ?>" /></div>
345                                                 <div class="star star3"><img src="<?php echo admin_url('images/star.gif'); ?>" alt="<?php _e('3 stars') ?>" /></div>
346                                                 <div class="star star2"><img src="<?php echo admin_url('images/star.gif'); ?>" alt="<?php _e('2 stars') ?>" /></div>
347                                                 <div class="star star1"><img src="<?php echo admin_url('images/star.gif'); ?>" alt="<?php _e('1 star') ?>" /></div>
348                                         </div>
349                                 </td>
350                                 <td class="desc"><p><?php echo $description, $author; ?></p></td>
351                                 <td class="action-links"><?php if ( !empty($action_links) )     echo implode(' | ', $action_links); ?></td>
352                         </tr>
353                         <?php
354                         }
355                         ?>
356                 </tbody>
357         </table>
358
359         <div class="tablenav">
360                 <?php if ( $page_links )
361                                 echo "\t\t<div class='tablenav-pages'>$page_links</div>"; ?>
362                 <br class="clear" />
363         </div>
364
365 <?php
366 }
367
368 add_action('install_plugins_pre_plugin-information', 'install_plugin_information');
369
370 /**
371  * Display plugin information in dialog box form.
372  *
373  * @since 2.7.0
374  */
375 function install_plugin_information() {
376         global $tab;
377
378         $api = plugins_api('plugin_information', array('slug' => stripslashes( $_REQUEST['plugin'] ) ));
379
380         if ( is_wp_error($api) )
381                 wp_die($api);
382
383         $plugins_allowedtags = array('a' => array('href' => array(), 'title' => array(), 'target' => array()),
384                                                                 'abbr' => array('title' => array()), 'acronym' => array('title' => array()),
385                                                                 'code' => array(), 'pre' => array(), 'em' => array(), 'strong' => array(),
386                                                                 'div' => array(), 'p' => array(), 'ul' => array(), 'ol' => array(), 'li' => array(),
387                                                                 'h1' => array(), 'h2' => array(), 'h3' => array(), 'h4' => array(), 'h5' => array(), 'h6' => array(),
388                                                                 'img' => array('src' => array(), 'class' => array(), 'alt' => array()));
389         //Sanitize HTML
390         foreach ( (array)$api->sections as $section_name => $content )
391                 $api->sections[$section_name] = wp_kses($content, $plugins_allowedtags);
392         foreach ( array('version', 'author', 'requires', 'tested', 'homepage', 'downloaded', 'slug') as $key )
393                 $api->$key = wp_kses($api->$key, $plugins_allowedtags);
394
395         $section = isset($_REQUEST['section']) ? stripslashes( $_REQUEST['section'] ) : 'description'; //Default to the Description tab, Do not translate, API returns English.
396         if( empty($section) || ! isset($api->sections[ $section ]) )
397                 $section = array_shift( $section_titles = array_keys((array)$api->sections) );
398
399         iframe_header( __('Plugin Install') );
400         echo "<div id='$tab-header'>\n";
401         echo "<ul id='sidemenu'>\n";
402         foreach ( (array)$api->sections as $section_name => $content ) {
403
404                 $title = $section_name;
405                 $title = ucwords(str_replace('_', ' ', $title));
406
407                 $class = ( $section_name == $section ) ? ' class="current"' : '';
408                 $href = add_query_arg( array('tab' => $tab, 'section' => $section_name) );
409                 $href = clean_url($href);
410                 $san_title = attribute_escape(sanitize_title_with_dashes($title));
411                 echo "\t<li><a name='$san_title' target='' href='$href'$class>$title</a></li>\n";
412         }
413         echo "</ul>\n";
414         echo "</div>\n";
415         ?>
416         <div class="alignright fyi">
417                 <?php if ( ! empty($api->download_link) ) : ?>
418                 <p class="action-button">
419                 <?php
420                         //Default to a "new" plugin
421                         $type = 'install';
422                         //Check to see if this plugin is known to be installed, and has an update awaiting it.
423                         $update_plugins = get_option('update_plugins');
424                         foreach ( (array)$update_plugins->response as $file => $plugin ) {
425                                 if ( $plugin->slug === $api->slug ) {
426                                         $type = 'update_available';
427                                         $update_file = $file;
428                                         break;
429                                 }
430                         }
431                         if ( 'install' == $type && is_dir( WP_PLUGIN_DIR  . '/' . $api->slug ) ) {
432                                 $installed_plugin = get_plugins('/' . $api->slug);
433                                 if ( ! empty($installed_plugin) ) {
434                                         $key = array_shift( $key = array_keys($installed_plugin) ); //Use the first plugin regardless of the name, Could have issues for multiple-plugins in one directory if they share different version numbers
435                                         if ( version_compare($api->version, $installed_plugin[ $key ]['Version'], '>') ){
436                                                 $type = 'latest_installed';
437                                         } elseif ( version_compare($api->version, $installed_plugin[ $key ]['Version'], '<') ) {
438                                                 $type = 'newer_installed';
439                                                 $newer_version = $installed_plugin[ $key ]['Version'];
440                                         } else {
441                                                 //If the above update check failed, Then that probably means that the update checker has out-of-date information, force a refresh
442                                                 delete_option('update_plugins');
443                                                 $update_file = $api->slug . '/' . $key; //This code branch only deals with a plugin which is in a folder the same name as its slug, Doesnt support plugins which have 'non-standard' names
444                                                 $type = 'update_available';
445                                         }
446                                 }
447                         }
448
449                         switch ( $type ) :
450                                 default:
451                                 case 'install':
452                                         if ( current_user_can('install_plugins') ) :
453                                 ?><a href="<?php echo wp_nonce_url(admin_url('plugin-install.php?tab=install&plugin=' . $api->slug), 'install-plugin_' . $api->slug) ?>" target="_parent"><?php _e('Install Now') ?></a><?php
454                                         endif;
455                                 break;
456                                 case 'update_available':
457                                         if ( current_user_can('update_plugins') ) :
458                                                 ?><a href="<?php echo wp_nonce_url(admin_url('update.php?action=upgrade-plugin&plugin=' . $update_file), 'upgrade-plugin_' . $update_file) ?>" target="_parent"><?php _e('Install Update Now') ?></a><?php
459                                         endif;
460                                 break;
461                                 case 'newer_installed':
462                                         if ( current_user_can('install_plugins') || current_user_can('update_plugins') ) :
463                                         ?><a><?php printf(__('Newer Version (%s) Installed'), $newer_version) ?></a><?php
464                                         endif;
465                                 break;
466                                 case 'latest_installed':
467                                         if ( current_user_can('install_plugins') || current_user_can('update_plugins') ) :
468                                         ?><a><?php _e('Latest Version Installed') ?></a><?php
469                                         endif;
470                                 break;
471                         endswitch; ?>
472                 </p>
473                 <?php endif; ?>
474                 <h2 class="mainheader"><?php _e('FYI') ?></h2>
475                 <ul>
476 <?php if ( ! empty($api->version) ) : ?>
477                         <li><strong><?php _e('Version:') ?></strong> <?php echo $api->version ?></li>
478 <?php endif; if ( ! empty($api->author) ) : ?>
479                         <li><strong><?php _e('Author:') ?></strong> <?php echo links_add_target($api->author, '_blank') ?></li>
480 <?php endif; if ( ! empty($api->last_updated) ) : ?>
481                         <li><strong><?php _e('Last Updated:') ?></strong> <span title="<?php echo $api->last_updated ?>"><?php
482                                                         printf( __('%s ago'), human_time_diff(strtotime($api->last_updated)) ) ?></span></li>
483 <?php endif; if ( ! empty($api->requires) ) : ?>
484                         <li><strong><?php _e('Requires WordPress Version:') ?></strong> <?php printf(__('%s or higher'), $api->requires) ?></li>
485 <?php endif; if ( ! empty($api->tested) ) : ?>
486                         <li><strong><?php _e('Compatible up to:') ?></strong> <?php echo $api->tested ?></li>
487 <?php endif; if ( ! empty($api->downloaded) ) : ?>
488                         <li><strong><?php _e('Downloaded:') ?></strong> <?php printf(__ngettext('%s time', '%s times', $api->downloaded), number_format_i18n($api->downloaded)) ?></li>
489 <?php endif; if ( ! empty($api->slug) ) : ?>
490                         <li><a target="_blank" href="http://wordpress.org/extend/plugins/<?php echo $api->slug ?>/"><?php _e('WordPress.org Plugin Page &#187;') ?></a></li>
491 <?php endif; if ( ! empty($api->homepage) ) : ?>
492                         <li><a target="_blank" href="<?php echo $api->homepage ?>"><?php _e('Plugin Homepage  &#187;') ?></a></li>
493 <?php endif; ?>
494                 </ul>
495                 <h2><?php _e('Average Rating') ?></h2>
496                 <div class="star-holder" title="<?php printf(__ngettext('(based on %s rating)', '(based on %s ratings)', $api->num_ratings), number_format_i18n($api->num_ratings)); ?>">
497                         <div class="star star-rating" style="width: <?php echo attribute_escape($api->rating) ?>px"></div>
498                         <div class="star star5"><img src="<?php echo admin_url('images/star.gif'); ?>" alt="<?php _e('5 stars') ?>" /></div>
499                         <div class="star star4"><img src="<?php echo admin_url('images/star.gif'); ?>" alt="<?php _e('4 stars') ?>" /></div>
500                         <div class="star star3"><img src="<?php echo admin_url('images/star.gif'); ?>" alt="<?php _e('3 stars') ?>" /></div>
501                         <div class="star star2"><img src="<?php echo admin_url('images/star.gif'); ?>" alt="<?php _e('2 stars') ?>" /></div>
502                         <div class="star star1"><img src="<?php echo admin_url('images/star.gif'); ?>" alt="<?php _e('1 star') ?>" /></div>
503                 </div>
504                 <small><?php printf(__ngettext('(based on %s rating)', '(based on %s ratings)', $api->num_ratings), number_format_i18n($api->num_ratings)); ?></small>
505         </div>
506         <div id="section-holder" class="wrap">
507         <?php
508                 if ( version_compare($GLOBALS['wp_version'], $api->tested, '>') )
509                         echo '<div class="updated"><p>' . __('<strong>Warning:</strong> This plugin has <strong>not been tested</strong> with your current version of WordPress.') . '</p></div>';
510                 else if ( version_compare($GLOBALS['wp_version'], $api->requires, '<') )
511                         echo '<div class="updated"><p>' . __('<strong>Warning:</strong> This plugin has not been marked as <strong>compatible</strong> with your version of WordPress.') . '</p></div>';
512                 foreach ( (array)$api->sections as $section_name => $content ) {
513                         $title = $section_name;
514                         $title[0] = strtoupper($title[0]);
515                         $title = str_replace('_', ' ', $title);
516
517                         $content = links_add_base_url($content, 'http://wordpress.org/extend/plugins/' . $api->slug . '/');
518                         $content = links_add_target($content, '_blank');
519
520                         $san_title = attribute_escape(sanitize_title_with_dashes($title));
521
522                         $display = ( $section_name == $section ) ? 'block' : 'none';
523
524                         echo "\t<div id='section-{$san_title}' class='section' style='display: {$display};'>\n";
525                         echo "\t\t<h2 class='long-header'>$title</h2>";
526                         echo $content;
527                         echo "\t</div>\n";
528                 }
529         echo "</div>\n";
530
531         iframe_footer();
532         exit;
533 }
534
535
536 add_action('install_plugins_upload', 'upload_plugin');
537 function upload_plugin() {
538
539         if ( ! ( ( $uploads = wp_upload_dir() ) && false === $uploads['error'] ) )
540                 wp_die($uploads['error']);
541
542         if ( !empty($_FILES) )
543                 $filename = $_FILES['pluginzip']['name'];
544         else if ( isset($_GET['package']) )
545                 $filename = $_GET['package'];
546
547         check_admin_referer('plugin-upload');
548
549         echo '<div class="wrap">';
550         echo '<h2>', sprintf( __('Installing Plugin from file: %s'), basename($filename) ), '</h2>';
551
552         //Handle a newly uploaded file, Else assume it was
553         if ( !empty($_FILES) ) {
554                 $filename = wp_unique_filename( $uploads['basedir'], $filename );
555                 $local_file = $uploads['basedir'] . '/' . $filename;
556
557                 // Move the file to the uploads dir
558                 if ( false === @ move_uploaded_file( $_FILES['pluginzip']['tmp_name'], $local_file) )
559                         wp_die( sprintf( __('The uploaded file could not be moved to %s.' ), $uploads['path']));
560         } else {
561                 $local_file = $uploads['basedir'] . '/' . $filename;
562         }
563
564         do_plugin_install_local_package($local_file, $filename);
565         echo '</div>';
566 }
567
568 add_action('install_plugins_install', 'install_plugin');
569
570 /**
571  * Display plugin link and execute install.
572  *
573  * @since 2.7.0
574  */
575 function install_plugin() {
576
577         $plugin = isset($_REQUEST['plugin']) ? stripslashes( $_REQUEST['plugin'] ) : '';
578
579         check_admin_referer('install-plugin_' . $plugin);
580         $api = plugins_api('plugin_information', array('slug' => $plugin, 'fields' => array('sections' => false) ) ); //Save on a bit of bandwidth.
581
582         if ( is_wp_error($api) )
583                 wp_die($api);
584
585         echo '<div class="wrap">';
586         echo '<h2>', sprintf( __('Installing Plugin: %s'), $api->name . ' ' . $api->version ), '</h2>';
587
588         do_plugin_install($api->download_link, $api);
589         echo '</div>';
590
591 }
592
593 /**
594  * Retrieve plugin and install.
595  *
596  * @since 2.7.0
597  *
598  * @param string $download_url Download URL.
599  * @param object $plugin_information Optional. Plugin information
600  */
601 function do_plugin_install($download_url, $plugin_information = null) {
602         global $wp_filesystem;
603
604         if ( empty($download_url) ) {
605                 show_message( __('No plugin Specified') );
606                 return;
607         }
608
609         $plugin = isset($_REQUEST['plugin']) ? stripslashes( $_REQUEST['plugin'] ) : '';
610
611         $url = 'plugin-install.php?tab=install';
612         $url = add_query_arg(array('plugin' => $plugin, 'plugin_name' => stripslashes( $_REQUEST['plugin_name'] ), 'download_url' => stripslashes( $_REQUEST['download_url'] ) ), $url);
613
614         $url = wp_nonce_url($url, 'install-plugin_' . $plugin);
615         if ( false === ($credentials = request_filesystem_credentials($url)) )
616                 return;
617
618         if ( ! WP_Filesystem($credentials) ) {
619                 request_filesystem_credentials($url, '', true); //Failed to connect, Error and request again
620                 return;
621         }
622
623         if ( $wp_filesystem->errors->get_error_code() ) {
624                 foreach ( $wp_filesystem->errors->get_error_messages() as $message )
625                         show_message($message);
626                 return;
627         }
628
629         $result = wp_install_plugin( $download_url, 'show_message' );
630
631         if ( is_wp_error($result) ) {
632                 show_message($result);
633                 show_message( __('Installation Failed') );
634         } else {
635                 show_message( sprintf(__('Successfully installed the plugin <strong>%s %s</strong>.'), $plugin_information->name, $plugin_information->version) );
636                 $plugin_file = $result;
637
638                 $install_actions = apply_filters('install_plugin_complete_actions', array(
639                         'activate_plugin' => '<a href="' . wp_nonce_url('plugins.php?action=activate&amp;plugin=' . $plugin_file, 'activate-plugin_' . $plugin_file) . '" title="' . attribute_escape(__('Activate this plugin')) . '" target="_parent">' . __('Activate Plugin') . '</a>',
640                         'plugins_page' => '<a href="' . admin_url('plugins.php') . '" title="' . attribute_escape(__('Goto plugins page')) . '" target="_parent">' . __('Return to Plugins page') . '</a>'
641                                                         ), $plugin_information, $plugin_file);
642                 if ( ! empty($install_actions) )
643                         show_message('<strong>' . __('Actions:') . '</strong> ' . implode(' | ', (array)$install_actions));
644         }
645 }
646
647 /**
648  * Install a plugin from a local file.
649  *
650  * @since 2.7.0
651  *
652  * @param string $package Local Plugin zip
653  * @param string $filename Optional. Original filename
654  * @param object $plugin_information Optional. Plugin information
655  */
656 function do_plugin_install_local_package($package, $filename = '') {
657         global $wp_filesystem;
658
659         if ( empty($package) ) {
660                 show_message( __('No plugin Specified') );
661                 return;
662         }
663
664         if ( empty($filename) )
665                 $filename = basename($package);
666
667         $url = 'plugin-install.php?tab=upload';
668         $url = add_query_arg(array('package' => $filename), $url);
669
670         $url = wp_nonce_url($url, 'plugin-upload');
671         if ( false === ($credentials = request_filesystem_credentials($url)) )
672                 return;
673
674         if ( ! WP_Filesystem($credentials) ) {
675                 request_filesystem_credentials($url, '', true); //Failed to connect, Error and request again
676                 return;
677         }
678
679         if ( $wp_filesystem->errors->get_error_code() ) {
680                 foreach ( $wp_filesystem->errors->get_error_messages() as $message )
681                         show_message($message);
682                 return;
683         }
684
685         $result = wp_install_plugin_local_package( $package, 'show_message' );
686
687         if ( is_wp_error($result) ) {
688                 show_message($result);
689                 show_message( __('Installation Failed') );
690         } else {
691                 show_message( __('Successfully installed the plugin.') );
692                 $plugin_file = $result;
693
694                 $install_actions = apply_filters('install_plugin_complete_actions', array(
695                                                         'activate_plugin' => '<a href="' . wp_nonce_url('plugins.php?action=activate&amp;plugin=' . $plugin_file, 'activate-plugin_' . $plugin_file) . '" title="' . __('Activate this plugin') . '" target="_parent">' . __('Activate Plugin') . '</a>',
696                                                         'plugins_page' => '<a href="' . admin_url('plugins.php') . '" title="' . __('Goto plugins page') . '" target="_parent">' . __('Return to Plugins page') . '</a>'
697                                                         ), array(), $plugin_file);
698                 if ( ! empty($install_actions) )
699                         show_message('<strong>' . __('Actions:') . '</strong> ' . implode(' | ', (array)$install_actions));
700         }
701 }
702
703 /**
704  * Install plugin.
705  *
706  * @since 2.7.0
707  *
708  * @param string $package
709  * @param string $feedback Optional.
710  * @return mixed.
711  */
712 function wp_install_plugin($package, $feedback = '') {
713         global $wp_filesystem;
714
715         if ( !empty($feedback) )
716                 add_filter('install_feedback', $feedback);
717
718         // Is a filesystem accessor setup?
719         if ( ! $wp_filesystem || ! is_object($wp_filesystem) )
720                 WP_Filesystem();
721
722         if ( ! is_object($wp_filesystem) )
723                 return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
724
725         if ( $wp_filesystem->errors->get_error_code() )
726                 return new WP_Error('fs_error', __('Filesystem error'), $wp_filesystem->errors);
727
728         //Get the base plugin folder
729         $plugins_dir = $wp_filesystem->wp_plugins_dir();
730         if ( empty($plugins_dir) )
731                 return new WP_Error('fs_no_plugins_dir', __('Unable to locate WordPress Plugin directory.'));
732
733         //And the same for the Content directory.
734         $content_dir = $wp_filesystem->wp_content_dir();
735         if( empty($content_dir) )
736                 return new WP_Error('fs_no_content_dir', __('Unable to locate WordPress Content directory (wp-content).'));
737
738         $plugins_dir = trailingslashit( $plugins_dir );
739         $content_dir = trailingslashit( $content_dir );
740
741         if ( empty($package) )
742                 return new WP_Error('no_package', __('Install package not available.'));
743
744         // Download the package
745         apply_filters('install_feedback', sprintf(__('Downloading plugin package from %s'), $package));
746         $download_file = download_url($package);
747
748         if ( is_wp_error($download_file) )
749                 return new WP_Error('download_failed', __('Download failed.'), $download_file->get_error_message());
750
751         $working_dir = $content_dir . 'upgrade/' . basename($package, '.zip');
752
753         // Clean up working directory
754         if ( $wp_filesystem->is_dir($working_dir) )
755                 $wp_filesystem->delete($working_dir, true);
756
757         apply_filters('install_feedback', __('Unpacking the plugin package'));
758         // Unzip package to working directory
759         $result = unzip_file($download_file, $working_dir);
760
761         // Once extracted, delete the package
762         @unlink($download_file);
763
764         if ( is_wp_error($result) ) {
765                 $wp_filesystem->delete($working_dir, true);
766                 return $result;
767         }
768
769         //Get a list of the directories in the working directory before we delete it, We need to know the new folder for the plugin
770         $filelist = array_keys( $wp_filesystem->dirlist($working_dir) );
771
772         if( $wp_filesystem->exists( $plugins_dir . $filelist[0] ) ) {
773                 $wp_filesystem->delete($working_dir, true);
774                 return new WP_Error('install_folder_exists', __('Folder already exists.'), $filelist[0] );
775         }
776
777         apply_filters('install_feedback', __('Installing the plugin'));
778         // Copy new version of plugin into place.
779         $result = copy_dir($working_dir, $plugins_dir);
780         if ( is_wp_error($result) ) {
781                 $wp_filesystem->delete($working_dir, true);
782                 return $result;
783         }
784
785         //Get a list of the directories in the working directory before we delete it, We need to know the new folder for the plugin
786         $filelist = array_keys( $wp_filesystem->dirlist($working_dir) );
787
788         // Remove working directory
789         $wp_filesystem->delete($working_dir, true);
790
791         if( empty($filelist) )
792                 return false; //We couldnt find any files in the working dir, therefor no plugin installed? Failsafe backup.
793
794         $folder = $filelist[0];
795         $plugin = get_plugins('/' . $folder); //Ensure to pass with leading slash
796         $pluginfiles = array_keys($plugin); //Assume the requested plugin is the first in the list
797
798         //Return the plugin files name.
799         return  $folder . '/' . $pluginfiles[0];
800 }
801
802 /**
803  * Install plugin from local package
804  *
805  * @since 2.7.0
806  *
807  * @param string $package
808  * @param string $feedback Optional.
809  * @return mixed.
810  */
811 function wp_install_plugin_local_package($package, $feedback = '') {
812         global $wp_filesystem;
813
814         if ( !empty($feedback) )
815                 add_filter('install_feedback', $feedback);
816
817         // Is a filesystem accessor setup?
818         if ( ! $wp_filesystem || ! is_object($wp_filesystem) )
819                 WP_Filesystem();
820
821         if ( ! is_object($wp_filesystem) )
822                 return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
823
824         if ( $wp_filesystem->errors->get_error_code() )
825                 return new WP_Error('fs_error', __('Filesystem error'), $wp_filesystem->errors);
826
827         //Get the base plugin folder
828         $plugins_dir = $wp_filesystem->wp_plugins_dir();
829         if ( empty($plugins_dir) )
830                 return new WP_Error('fs_no_plugins_dir', __('Unable to locate WordPress Plugin directory.'));
831
832         //And the same for the Content directory.
833         $content_dir = $wp_filesystem->wp_content_dir();
834         if( empty($content_dir) )
835                 return new WP_Error('fs_no_content_dir', __('Unable to locate WordPress Content directory (wp-content).'));
836
837         $plugins_dir = trailingslashit( $plugins_dir );
838         $content_dir = trailingslashit( $content_dir );
839
840         if ( empty($package) )
841                 return new WP_Error('no_package', __('Install package not available.'));
842
843         $working_dir = $content_dir . 'upgrade/' . basename($package, '.zip');
844
845         // Clean up working directory
846         if ( $wp_filesystem->is_dir($working_dir) )
847                 $wp_filesystem->delete($working_dir, true);
848
849         apply_filters('install_feedback', __('Unpacking the plugin package'));
850         // Unzip package to working directory
851         $result = unzip_file($package, $working_dir);
852
853         // Once extracted, delete the package
854         unlink($package);
855
856         if ( is_wp_error($result) ) {
857                 $wp_filesystem->delete($working_dir, true);
858                 return $result;
859         }
860
861         //Get a list of the directories in the working directory before we delete it, We need to know the new folder for the plugin
862         $filelist = array_keys( $wp_filesystem->dirlist($working_dir) );
863
864         if( $wp_filesystem->exists( $plugins_dir . $filelist[0] ) ) {
865                 $wp_filesystem->delete($working_dir, true);
866                 return new WP_Error('install_folder_exists', __('Folder already exists.'), $filelist[0] );
867         }
868
869         apply_filters('install_feedback', __('Installing the plugin'));
870         // Copy new version of plugin into place.
871         $result = copy_dir($working_dir, $plugins_dir);
872         if ( is_wp_error($result) ) {
873                 $wp_filesystem->delete($working_dir, true);
874                 return $result;
875         }
876
877         //Get a list of the directories in the working directory before we delete it, We need to know the new folder for the plugin
878         $filelist = array_keys( $wp_filesystem->dirlist($working_dir) );
879
880         // Remove working directory
881         $wp_filesystem->delete($working_dir, true);
882
883         if( empty($filelist) )
884                 return false; //We couldnt find any files in the working dir, therefor no plugin installed? Failsafe backup.
885
886         $folder = $filelist[0];
887         $plugin = get_plugins('/' . $folder); //Ensure to pass with leading slash
888         $pluginfiles = array_keys($plugin); //Assume the requested plugin is the first in the list
889
890         //Return the plugin files name.
891         return  $folder . '/' . $pluginfiles[0];
892 }
893
894 ?>