2011-11-02 04:14:14 +00:00
<? php
2008-09-17 00:40:10 +00:00
/**
* WordPress Plugin Install Administration API
*
* @package WordPress
* @subpackage Administration
*/
/**
2015-09-27 22:07:24 +00:00
* Retrieves plugin installer pages from the WordPress.org Plugins API.
2008-09-17 00:40:10 +00:00
*
* It is possible for a plugin to override the Plugin API result with three
* filters. Assume this is for plugins, which can extend on the Plugin Info to
2015-09-26 15:13:25 +00:00
* offer more choices. This is very powerful and must be used with care when
2011-09-05 19:25:55 +00:00
* overriding the filters.
2008-09-17 00:40:10 +00:00
*
2015-09-26 15:13:25 +00:00
* The first filter, {@see 'plugins_api_args'}, is for the args and gives the action
* as the second parameter. The hook for {@see 'plugins_api_args'} must ensure that
* an object is returned.
2008-09-17 00:40:10 +00:00
*
2015-09-27 22:23:24 +00:00
* The second filter, {@see 'plugins_api'}, allows a plugin to override the WordPress.org
2015-10-02 04:48:25 +00:00
* Plugin Install API entirely. If `$action` is 'query_plugins' or 'plugin_information',
2016-07-09 14:39:33 +00:00
* an object MUST be passed. If `$action` is 'hot_tags' or 'hot_categories', an array MUST
2015-09-27 22:23:24 +00:00
* be passed.
*
* Finally, the third filter, {@see 'plugins_api_result'}, makes it possible to filter the
* response object or array, depending on the `$action` type.
2008-09-17 00:40:10 +00:00
*
2015-09-27 22:00:25 +00:00
* Supported arguments per action:
*
* | Argument Name | query_plugins | plugin_information | hot_tags | hot_categories |
* | -------------------- | :-----------: | :----------------: | :------: | :------------: |
* | `$slug` | No | Yes | No | No |
* | `$per_page` | Yes | No | No | No |
* | `$page` | Yes | No | No | No |
* | `$number` | No | No | Yes | Yes |
* | `$search` | Yes | No | No | No |
* | `$tag` | Yes | No | No | No |
* | `$author` | Yes | No | No | No |
* | `$user` | Yes | No | No | No |
* | `$browse` | Yes | No | No | No |
* | `$locale` | Yes | Yes | No | No |
* | `$installed_plugins` | Yes | No | No | No |
* | `$is_ssl` | Yes | Yes | No | No |
* | `$fields` | Yes | Yes | No | No |
*
2008-10-10 18:21:16 +00:00
* @since 2.7.0
*
2015-09-26 15:13:25 +00:00
* @param string $action API action to perform: 'query_plugins', 'plugin_information',
* 'hot_tags' or 'hot_categories'.
* @param array|object $args {
* Optional. Array or object of arguments to serialize for the Plugin Info API.
*
2015-09-27 18:13:48 +00:00
* @type string $slug The plugin slug. Default empty.
* @type int $per_page Number of plugins per page. Default 24.
* @type int $page Number of current page. Default 1.
* @type int $number Number of tags or categories to be queried.
* @type string $search A search term. Default empty.
* @type string $tag Tag to filter plugins. Default empty.
* @type string $author Username of an plugin author to filter plugins. Default empty.
* @type string $user Username to query for their favorites. Default empty.
* @type string $browse Browse view: 'popular', 'new', 'beta', 'recommended'.
* @type string $locale Locale to provide context-sensitive results. Default is the value
* of get_locale().
* @type string $installed_plugins Installed plugins to provide context-sensitive results.
* @type bool $is_ssl Whether links should be returned with https or not. Default false.
* @type array $fields {
2015-09-26 15:13:25 +00:00
* Array of fields which should or should not be returned.
*
* @type bool $short_description Whether to return the plugin short description. Default true.
* @type bool $description Whether to return the plugin full description. Default false.
* @type bool $sections Whether to return the plugin readme sections: description, installation,
* FAQ, screenshots, other notes, and changelog. Default false.
* @type bool $tested Whether to return the 'Compatible up to' value. Default true.
* @type bool $requires Whether to return the required WordPress version. Default true.
* @type bool $rating Whether to return the rating in percent and total number of ratings.
* Default true.
* @type bool $ratings Whether to return the number of rating for each star (1-5). Default true.
* @type bool $downloaded Whether to return the download count. Default true.
* @type bool $downloadlink Whether to return the download link for the package. Default true.
* @type bool $last_updated Whether to return the date of the last update. Default true.
* @type bool $added Whether to return the date when the plugin was added to the wordpress.org
* repository. Default true.
* @type bool $tags Whether to return the assigned tags. Default true.
* @type bool $compatibility Whether to return the WordPress compatibility list. Default true.
* @type bool $homepage Whether to return the plugin homepage link. Default true.
* @type bool $versions Whether to return the list of all available versions. Default false.
* @type bool $donate_link Whether to return the donation link. Default true.
* @type bool $reviews Whether to return the plugin reviews. Default false.
* @type bool $banners Whether to return the banner images links. Default false.
* @type bool $icons Whether to return the icon links. Default false.
* @type bool $active_installs Whether to return the number of active installs. Default false.
* @type bool $group Whether to return the assigned group. Default false.
* @type bool $contributors Whether to return the list of contributors. Default false.
* }
* }
2015-09-27 22:00:25 +00:00
* @return object|array|WP_Error Response object or array on success, WP_Error on failure. See the
2015-09-26 15:13:25 +00:00
* {@link https://developer.wordpress.org/reference/functions/plugins_api/ function reference article}
2015-09-27 22:00:25 +00:00
* for more information on the make-up of possible return values depending on the value of `$action`.
2008-09-17 00:40:10 +00:00
*/
2015-09-26 15:13:25 +00:00
function plugins_api ( $action , $args = array () ) {
2008-08-04 21:17:42 +00:00
2014-12-16 22:39:22 +00:00
if ( is_array ( $args ) ) {
$args = ( object ) $args ;
}
2008-08-04 21:17:42 +00:00
2014-12-16 22:39:22 +00:00
if ( ! isset ( $args -> per_page ) ) {
2008-11-20 21:22:24 +00:00
$args -> per_page = 24 ;
2014-12-16 22:39:22 +00:00
}
if ( ! isset ( $args -> locale ) ) {
2016-10-03 07:04:29 +00:00
$args -> locale = get_user_locale ();
2014-12-16 22:39:22 +00:00
}
2008-11-20 21:22:24 +00:00
2013-09-20 02:22:10 +00:00
/**
2016-05-22 18:01:30 +00:00
* Filters the WordPress.org Plugin Install API arguments.
2013-09-20 02:22:10 +00:00
*
2015-09-27 23:03:24 +00:00
* Important: An object MUST be returned to this filter.
2013-09-20 02:22:10 +00:00
*
* @since 2.7.0
*
* @param object $args Plugin API arguments.
* @param string $action The type of information being requested from the Plugin Install API.
*/
$args = apply_filters ( 'plugins_api_args' , $args , $action );
/**
2016-05-22 18:01:30 +00:00
* Filters the response for the current WordPress.org Plugin Install API request.
2013-09-20 02:22:10 +00:00
*
2015-09-27 22:29:24 +00:00
* Passing a non-false value will effectively short-circuit the WordPress.org API request.
*
2015-10-02 04:52:25 +00:00
* If `$action` is 'query_plugins' or 'plugin_information', an object MUST be passed.
2016-07-09 14:39:33 +00:00
* If `$action` is 'hot_tags' or 'hot_categories', an array should be passed.
2013-09-20 02:22:10 +00:00
*
* @since 2.7.0
*
2015-09-27 22:29:24 +00:00
* @param false|object|array $result The result object or array. Default false.
* @param string $action The type of information being requested from the Plugin Install API.
* @param object $args Plugin API arguments.
2013-09-20 02:22:10 +00:00
*/
$res = apply_filters ( 'plugins_api' , false , $action , $args );
2008-08-09 05:36:14 +00:00
2010-01-17 03:26:50 +00:00
if ( false === $res ) {
2013-10-27 21:09:10 +00:00
$url = $http_url = 'http://api.wordpress.org/plugins/info/1.0/' ;
if ( $ssl = wp_http_supports ( array ( 'ssl' ) ) )
2013-09-09 07:54:11 +00:00
$url = set_url_scheme ( $url , 'https' );
2015-02-07 06:21:22 +00:00
$http_args = array (
2013-09-09 07:54:11 +00:00
'timeout' => 15 ,
'body' => array (
'action' => $action ,
'request' => serialize ( $args )
)
2013-10-27 21:09:10 +00:00
);
2015-02-07 06:21:22 +00:00
$request = wp_remote_post ( $url , $http_args );
2013-10-27 21:09:10 +00:00
if ( $ssl && is_wp_error ( $request ) ) {
2016-11-21 01:52:32 +00:00
trigger_error (
sprintf (
/* translators: %s: support forums URL */
__ ( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ),
__ ( 'https://wordpress.org/support/' )
) . ' ' . __ ( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ),
headers_sent () || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE
);
2015-02-07 06:21:22 +00:00
$request = wp_remote_post ( $http_url , $http_args );
2013-10-27 21:09:10 +00:00
}
2013-09-09 07:54:11 +00:00
2008-10-14 15:56:33 +00:00
if ( is_wp_error ( $request ) ) {
2016-11-21 01:52:32 +00:00
$res = new WP_Error ( 'plugins_api_failed' ,
sprintf (
/* translators: %s: support forums URL */
__ ( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ),
__ ( 'https://wordpress.org/support/' )
),
$request -> get_error_message ()
);
2008-10-14 15:56:33 +00:00
} else {
2012-01-08 03:48:05 +00:00
$res = maybe_unserialize ( wp_remote_retrieve_body ( $request ) );
2016-11-21 01:52:32 +00:00
if ( ! is_object ( $res ) && ! is_array ( $res ) ) {
$res = new WP_Error ( 'plugins_api_failed' ,
sprintf (
/* translators: %s: support forums URL */
__ ( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ),
__ ( 'https://wordpress.org/support/' )
),
wp_remote_retrieve_body ( $request )
);
}
2008-10-14 15:56:33 +00:00
}
2009-06-16 19:36:48 +00:00
} elseif ( ! is_wp_error ( $res ) ) {
$res -> external = true ;
2008-08-04 21:17:42 +00:00
}
2013-09-20 02:22:10 +00:00
/**
2016-05-22 18:01:30 +00:00
* Filters the Plugin Install API response results.
2013-09-20 02:22:10 +00:00
*
* @since 2.7.0
*
* @param object|WP_Error $res Response object or WP_Error.
* @param string $action The type of information being requested from the Plugin Install API.
* @param object $args Plugin API arguments.
*/
return apply_filters ( 'plugins_api_result' , $res , $action , $args );
2008-08-04 21:17:42 +00:00
}
2008-09-17 00:40:10 +00:00
/**
2008-10-10 18:21:16 +00:00
* Retrieve popular WordPress plugin tags.
*
* @since 2.7.0
2008-09-17 00:40:10 +00:00
*
2008-10-10 18:21:16 +00:00
* @param array $args
* @return array
2008-09-17 00:40:10 +00:00
*/
2008-08-04 21:17:42 +00:00
function install_popular_tags ( $args = array () ) {
2010-06-19 07:28:27 +00:00
$key = md5 ( serialize ( $args ));
if ( false !== ( $tags = get_site_transient ( 'poptags_' . $key ) ) )
return $tags ;
2008-08-04 21:17:42 +00:00
2008-08-05 17:06:42 +00:00
$tags = plugins_api ( 'hot_tags' , $args );
2008-08-04 21:17:42 +00:00
2008-10-14 15:56:33 +00:00
if ( is_wp_error ( $tags ) )
return $tags ;
2012-09-25 05:26:19 +00:00
set_site_transient ( 'poptags_' . $key , $tags , 3 * HOUR_IN_SECONDS );
2008-08-04 21:17:42 +00:00
return $tags ;
}
2008-10-10 18:21:16 +00:00
2015-05-31 03:18:25 +00:00
/**
* @since 2.7.0
*/
2008-10-13 23:39:56 +00:00
function install_dashboard () {
2008-08-04 21:17:42 +00:00
?>
2016-08-23 01:19:39 +00:00
<p><?php printf( __( 'Plugins extend and expand the functionality of WordPress. You may automatically install plugins from the <a href="%1$s">WordPress Plugin Directory</a> or upload a plugin in .zip format by clicking the button at the top of this page.' ), __( 'https://wordpress.org/plugins/' ) ); ?></p>
2008-08-09 05:36:14 +00:00
2014-08-27 02:53:16 +00:00
<?php display_plugins_table(); ?>
2008-12-09 18:03:31 +00:00
2016-07-20 16:32:31 +00:00
<div class="plugins-popular-tags-wrapper">
2015-10-10 15:17:26 +00:00
<h2><?php _e( 'Popular tags' ) ?></h2>
2014-08-27 02:53:16 +00:00
<p><?php _e( 'You may also browse based on the most popular tags in the Plugin Directory:' ) ?></p>
2008-08-04 21:17:42 +00:00
<?php
2008-10-10 18:21:16 +00:00
$api_tags = install_popular_tags();
2008-08-04 21:17:42 +00:00
2009-03-20 00:14:57 +00:00
echo '<p class="popular-tags">';
2010-04-25 05:39:39 +00:00
if ( is_wp_error($api_tags) ) {
echo $api_tags->get_error_message();
} else {
2011-09-03 14:18:10 +00:00
//Set up the tags in a way which can be interpreted by wp_generate_tag_cloud()
2010-04-25 05:39:39 +00:00
$tags = array();
2015-07-07 19:19:24 +00:00
foreach ( (array) $api_tags as $tag ) {
$url = self_admin_url( 'plugin-install.php?tab=search&type=tag&s=' . urlencode( $tag['name'] ) );
$data = array(
'link' => esc_url( $url ),
'name' => $tag['name'],
'slug' => $tag['slug'],
'id' => sanitize_title_with_dashes( $tag['name'] ),
'count' => $tag['count']
);
$tags[ $tag['name'] ] = (object) $data;
}
2011-11-02 02:36:18 +00:00
echo wp_generate_tag_cloud($tags, array( 'single_text' => __('%s plugin'), 'multiple_text' => __('%s plugins') ) );
2010-04-25 05:39:39 +00:00
}
2016-07-20 16:32:31 +00:00
echo '</p><br class="clear" /></div>';
2008-08-04 21:17:42 +00:00
}
2008-10-18 20:46:30 +00:00
/**
2016-07-20 16:32:31 +00:00
* Displays a search form for searching plugins.
2008-10-18 20:46:30 +00:00
*
* @since 2.7.0
2016-07-20 16:32:31 +00:00
* @since 4.6.0 The `$type_selector` parameter was deprecated.
2015-05-29 21:17:27 +00:00
*
2016-07-20 16:32:31 +00:00
* @param bool $deprecated Not used.
2008-10-18 20:46:30 +00:00
*/
2016-07-20 16:32:31 +00:00
function install_search_form( $deprecated = true ) {
$type = isset( $_REQUEST['type'] ) ? wp_unslash( $_REQUEST['type'] ) : 'term';
$term = isset( $_REQUEST['s'] ) ? wp_unslash( $_REQUEST['s'] ) : '';
2015-01-16 04:16:24 +00:00
?><form class="search-form search-plugins" method="get">
2010-08-11 21:54:51 +00:00
<input type="hidden" name="tab" value="search" />
2016-07-20 16:32:31 +00:00
<label class="screen-reader-text" for="typeselector"><?php _e( 'Search plugins by:' ); ?></label>
2008-08-04 21:17:42 +00:00
<select name="type" id="typeselector">
2016-07-20 16:32:31 +00:00
<option value="term"<?php selected( 'term', $type ); ?>><?php _e( 'Keyword' ); ?></option>
<option value="author"<?php selected( 'author', $type ); ?>><?php _e( 'Author' ); ?></option>
<option value="tag"<?php selected( 'tag', $type ); ?>><?php _ex( 'Tag', 'Plugin Installer' ); ?></option>
2008-08-04 21:17:42 +00:00
</select>
2016-07-20 16:32:31 +00:00
<label><span class="screen-reader-text"><?php _e( 'Search Plugins' ); ?></span>
2016-10-14 21:33:28 +00:00
<input type="search" name="s" value="<?php echo esc_attr( $term ) ?>" class="wp-filter-search" placeholder="<?php esc_attr_e( 'Search plugins...' ); ?>" />
2014-07-18 04:50:15 +00:00
</label>
2016-09-28 19:54:28 +00:00
<?php submit_button( __( 'Search Plugins' ), 'hide-if-js', false, false, array( 'id' => 'search-submit' ) ); ?>
2008-08-04 21:17:42 +00:00
</form><?php
}
2009-03-20 13:31:00 +00:00
/**
* Upload from zip
* @since 2.8.0
*/
2015-02-03 06:14:22 +00:00
function install_plugins_upload() {
2009-03-20 13:31:00 +00:00
?>
2014-08-27 01:32:18 +00:00
<div class="upload-plugin">
2012-11-07 23:54:03 +00:00
<p class="install-help"><?php _e('If you have a plugin in a .zip format, you may install it by uploading it here.'); ?></p>
<form method="post" enctype="multipart/form-data" class="wp-upload-form" action="<?php echo self_admin_url('update.php?action=upload-plugin'); ?>">
2015-12-16 07:56:29 +00:00
<?php wp_nonce_field( 'plugin-upload' ); ?>
<label class="screen-reader-text" for="pluginzip"><?php _e( 'Plugin zip file' ); ?></label>
2009-05-01 21:52:34 +00:00
<input type="file" id="pluginzip" name="pluginzip" />
2016-09-28 19:54:28 +00:00
<?php submit_button( __( 'Install Now' ), '', 'install-plugin-submit', false ); ?>
2009-03-20 13:31:00 +00:00
</form>
2014-08-27 01:32:18 +00:00
</div>
2009-03-20 13:31:00 +00:00
<?php
}
2008-08-04 21:17:42 +00:00
2012-09-27 00:47:01 +00:00
/**
* Show a username form for the favorites page
* @since 3.5.0
*
*/
function install_plugins_favorites_form() {
2016-03-30 18:36:26 +00:00
$user = get_user_option( 'wporg_favorites' );
$action = 'save_wporg_username_' . get_current_user_id();
2012-09-27 00:47:01 +00:00
?>
<p class="install-help"><?php _e( 'If you have marked plugins as favorites on WordPress.org, you can browse them here.' ); ?></p>
2015-01-16 04:16:24 +00:00
<form method="get">
2012-09-27 00:47:01 +00:00
<input type="hidden" name="tab" value="favorites" />
<p>
<label for="user"><?php _e( 'Your WordPress.org username:' ); ?></label>
<input type="search" id="user" name="user" value="<?php echo esc_attr( $user ); ?>" />
<input type="submit" class="button" value="<?php esc_attr_e( 'Get Favorites' ); ?>" />
2016-04-02 11:12:26 +00:00
<input type="hidden" id="wporg-username-nonce" name="_wpnonce" value="<?php echo esc_attr( wp_create_nonce( $action ) ); ?>" />
2012-09-27 00:47:01 +00:00
</p>
</form>
<?php
}
2008-10-10 18:21:16 +00:00
/**
* Display plugin content based on plugin list.
*
* @since 2.7.0
2015-05-28 21:41:30 +00:00
*
* @global WP_List_Table $wp_list_table
2008-10-10 18:21:16 +00:00
*/
2010-08-11 21:54:51 +00:00
function display_plugins_table() {
2010-08-22 11:22:46 +00:00
global $wp_list_table;
2008-08-04 21:17:42 +00:00
2014-12-16 10:06:24 +00:00
switch ( current_filter() ) {
case 'install_plugins_favorites' :
if ( empty( $_GET['user'] ) && ! get_user_option( 'wporg_favorites' ) ) {
return;
}
break;
case 'install_plugins_recommended' :
echo '<p>' . __( 'These suggestions are based on the plugins you and other users have installed.' ) . '</p>';
break;
2016-01-14 09:07:26 +00:00
case 'install_plugins_beta' :
printf(
'<p>' . __( 'You are using a development version of WordPress. These feature plugins are also under development. <a href="%s">Learn more</a>.' ) . '</p>',
'https://make.wordpress.org/core/handbook/about/release-cycle/features-as-plugins/'
);
break;
2014-10-03 13:08:16 +00:00
}
2012-09-27 00:47:01 +00:00
2014-10-03 13:08:16 +00:00
?>
2015-01-16 04:16:24 +00:00
<form id="plugin-filter" method="post">
2014-10-03 13:08:16 +00:00
<?php $wp_list_table->display(); ?>
</form>
<?php
2008-08-04 21:17:42 +00:00
}
2008-10-10 18:21:16 +00:00
2010-04-01 23:17:53 +00:00
/**
* Determine the status we can perform on a plugin.
*
* @since 3.0.0
2015-05-29 21:17:27 +00:00
*
2016-10-17 08:30:29 +00:00
* @param array|object $api Data about the plugin retrieved from the API.
* @param bool $loop Optional. Disable further loops. Default false.
* @return array {
* Plugin installation status data.
*
* @type string $status Status of a plugin. Could be one of 'install', 'update_available', 'latest_installed' or 'newer_installed'.
* @type string $url Plugin installation URL.
* @type string $version The most recent version of the plugin.
* @type string $file Plugin filename relative to the plugins directory.
* }
2010-04-01 23:17:53 +00:00
*/
function install_plugin_install_status($api, $loop = false) {
2014-07-17 09:14:16 +00:00
// This function is called recursively, $loop prevents further loops.
2010-04-01 23:17:53 +00:00
if ( is_array($api) )
$api = (object) $api;
2014-07-17 09:14:16 +00:00
// Default to a "new" plugin
2010-04-01 23:17:53 +00:00
$status = 'install';
$url = false;
2015-02-05 04:19:23 +00:00
$update_file = false;
2010-04-01 23:17:53 +00:00
2014-07-17 09:14:16 +00:00
/*
* Check to see if this plugin is known to be installed,
* and has an update awaiting it.
*/
2010-04-01 23:17:53 +00:00
$update_plugins = get_site_transient('update_plugins');
2012-04-17 02:43:13 +00:00
if ( isset( $update_plugins->response ) ) {
2010-04-01 23:17:53 +00:00
foreach ( (array)$update_plugins->response as $file => $plugin ) {
if ( $plugin->slug === $api->slug ) {
$status = 'update_available';
$update_file = $file;
$version = $plugin->new_version;
if ( current_user_can('update_plugins') )
2010-10-20 14:16:03 +00:00
$url = wp_nonce_url(self_admin_url('update.php?action=upgrade-plugin&plugin=' . $update_file), 'upgrade-plugin_' . $update_file);
2010-04-01 23:17:53 +00:00
break;
}
}
}
if ( 'install' == $status ) {
2011-12-13 23:45:31 +00:00
if ( is_dir( WP_PLUGIN_DIR . '/' . $api->slug ) ) {
2010-04-01 23:17:53 +00:00
$installed_plugin = get_plugins('/' . $api->slug);
if ( empty($installed_plugin) ) {
if ( current_user_can('install_plugins') )
2010-10-20 14:16:03 +00:00
$url = wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=' . $api->slug), 'install-plugin_' . $api->slug);
2010-04-01 23:17:53 +00:00
} else {
2013-07-17 21:08:05 +00:00
$key = array_keys( $installed_plugin );
2015-03-19 03:56:27 +00:00
$key = reset( $key ); //Use the first plugin regardless of the name, Could have issues for multiple-plugins in one directory if they share different version numbers
2015-02-05 04:19:23 +00:00
$update_file = $api->slug . '/' . $key;
2010-04-01 23:17:53 +00:00
if ( version_compare($api->version, $installed_plugin[ $key ]['Version'], '=') ){
$status = 'latest_installed';
} elseif ( version_compare($api->version, $installed_plugin[ $key ]['Version'], '<') ) {
$status = 'newer_installed';
$version = $installed_plugin[ $key ]['Version'];
} else {
//If the above update check failed, Then that probably means that the update checker has out-of-date information, force a refresh
if ( ! $loop ) {
delete_site_transient('update_plugins');
wp_update_plugins();
return install_plugin_install_status($api, true);
}
}
}
} else {
// "install" & no directory with that slug
if ( current_user_can('install_plugins') )
2010-10-20 14:16:03 +00:00
$url = wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=' . $api->slug), 'install-plugin_' . $api->slug);
2010-04-01 23:17:53 +00:00
}
}
2010-05-27 11:04:08 +00:00
if ( isset($_GET['from']) )
2013-03-01 17:00:25 +00:00
$url .= '&from=' . urlencode( wp_unslash( $_GET['from'] ) );
2010-04-01 23:17:53 +00:00
2015-02-05 04:19:23 +00:00
$file = $update_file;
return compact( 'status', 'url', 'version', 'file' );
2010-04-01 23:17:53 +00:00
}
2008-10-10 18:21:16 +00:00
/**
* Display plugin information in dialog box form.
*
* @since 2.7.0
2015-05-28 21:41:30 +00:00
*
* @global string $tab
2008-10-10 18:21:16 +00:00
*/
2008-08-04 21:17:42 +00:00
function install_plugin_information() {
global $tab;
2008-08-09 05:36:14 +00:00
2014-10-12 13:06:19 +00:00
if ( empty( $_REQUEST['plugin'] ) ) {
return;
}
2014-07-12 22:08:16 +00:00
$api = plugins_api( 'plugin_information', array(
'slug' => wp_unslash( $_REQUEST['plugin'] ),
'is_ssl' => is_ssl(),
2015-04-02 23:49:27 +00:00
'fields' => array(
'banners' => true,
'reviews' => true,
'downloaded' => false,
'active_installs' => true
)
2014-07-12 22:08:16 +00:00
) );
2008-08-04 21:17:42 +00:00
2014-07-12 22:08:16 +00:00
if ( is_wp_error( $api ) ) {
2014-03-16 18:28:17 +00:00
wp_die( $api );
2014-07-12 22:08:16 +00:00
}
2008-10-14 15:56:33 +00:00
2012-01-08 09:18:56 +00:00
$plugins_allowedtags = array(
'a' => array( 'href' => array(), 'title' => array(), 'target' => array() ),
'abbr' => array( 'title' => array() ), 'acronym' => array( 'title' => array() ),
'code' => array(), 'pre' => array(), 'em' => array(), 'strong' => array(),
2014-08-16 03:07:18 +00:00
'div' => array( 'class' => array() ), 'span' => array( 'class' => array() ),
'p' => array(), 'ul' => array(), 'ol' => array(), 'li' => array(),
2012-01-08 09:18:56 +00:00
'h1' => array(), 'h2' => array(), 'h3' => array(), 'h4' => array(), 'h5' => array(), 'h6' => array(),
'img' => array( 'src' => array(), 'class' => array(), 'alt' => array() )
);
2012-01-08 05:39:49 +00:00
$plugins_section_titles = array(
2014-07-12 22:08:16 +00:00
'description' => _x( 'Description', 'Plugin installer section title' ),
'installation' => _x( 'Installation', 'Plugin installer section title' ),
'faq' => _x( 'FAQ', 'Plugin installer section title' ),
'screenshots' => _x( 'Screenshots', 'Plugin installer section title' ),
'changelog' => _x( 'Changelog', 'Plugin installer section title' ),
'reviews' => _x( 'Reviews', 'Plugin installer section title' ),
'other_notes' => _x( 'Other Notes', 'Plugin installer section title' )
2012-01-08 09:18:56 +00:00
);
2012-01-08 05:39:49 +00:00
2014-07-12 22:08:16 +00:00
// Sanitize HTML
foreach ( (array) $api->sections as $section_name => $content ) {
$api->sections[$section_name] = wp_kses( $content, $plugins_allowedtags );
2014-03-16 18:28:17 +00:00
}
2011-08-23 15:56:14 +00:00
foreach ( array( 'version', 'author', 'requires', 'tested', 'homepage', 'downloaded', 'slug' ) as $key ) {
2014-07-12 22:08:16 +00:00
if ( isset( $api->$key ) ) {
2011-08-23 15:56:14 +00:00
$api->$key = wp_kses( $api->$key, $plugins_allowedtags );
2014-07-12 22:08:16 +00:00
}
2011-08-23 15:56:14 +00:00
}
2008-10-14 15:56:33 +00:00
2014-03-16 18:28:17 +00:00
$_tab = esc_attr( $tab );
2014-07-12 22:08:16 +00:00
$section = isset( $_REQUEST['section'] ) ? wp_unslash( $_REQUEST['section'] ) : 'description'; // Default to the Description tab, Do not translate, API returns English.
2013-09-02 13:54:10 +00:00
if ( empty( $section ) || ! isset( $api->sections[ $section ] ) ) {
$section_titles = array_keys( (array) $api->sections );
2015-03-19 03:56:27 +00:00
$section = reset( $section_titles );
2013-09-02 13:54:10 +00:00
}
2008-08-09 05:36:14 +00:00
2014-07-12 22:08:16 +00:00
iframe_header( __( 'Plugin Install' ) );
2014-08-15 17:17:16 +00:00
2014-07-09 17:28:17 +00:00
$_with_banner = '';
2014-07-12 22:08:16 +00:00
if ( ! empty( $api->banners ) && ( ! empty( $api->banners['low'] ) || ! empty( $api->banners['high'] ) ) ) {
2014-07-09 17:28:17 +00:00
$_with_banner = 'with-banner';
2014-07-12 22:08:16 +00:00
$low = empty( $api->banners['low'] ) ? $api->banners['high'] : $api->banners['low'];
$high = empty( $api->banners['high'] ) ? $api->banners['low'] : $api->banners['high'];
2014-07-09 17:28:17 +00:00
?>
<style type="text/css">
#plugin-information-title.with-banner {
2014-07-12 22:08:16 +00:00
background-image: url( <?php echo esc_url( $low ); ?> );
2014-07-09 17:28:17 +00:00
}
2014-07-12 22:08:16 +00:00
@media only screen and ( -webkit-min-device-pixel-ratio: 1.5 ) {
2014-07-09 17:28:17 +00:00
#plugin-information-title.with-banner {
2014-07-12 22:08:16 +00:00
background-image: url( <?php echo esc_url( $high ); ?> );
2014-07-09 17:28:17 +00:00
}
}
</style>
<?php
}
2014-08-12 23:02:16 +00:00
echo '<div id="plugin-information-scrollable">';
2014-07-09 17:28:17 +00:00
echo "<div id='{$_tab}-title' class='{$_with_banner}'><div class='vignette'></div><h2>{$api->name}</h2></div>";
echo "<div id='{$_tab}-tabs' class='{$_with_banner}'>\n";
2014-03-16 18:28:17 +00:00
2014-07-12 22:08:16 +00:00
foreach ( (array) $api->sections as $section_name => $content ) {
if ( 'reviews' === $section_name && ( empty( $api->ratings ) || 0 === array_sum( (array) $api->ratings ) ) ) {
2014-07-09 17:28:17 +00:00
continue;
2014-07-12 22:08:16 +00:00
}
2008-08-09 05:36:14 +00:00
2014-07-12 22:08:16 +00:00
if ( isset( $plugins_section_titles[ $section_name ] ) ) {
2012-01-08 05:39:49 +00:00
$title = $plugins_section_titles[ $section_name ];
2014-07-12 22:08:16 +00:00
} else {
2012-01-08 05:39:49 +00:00
$title = ucwords( str_replace( '_', ' ', $section_name ) );
2014-07-12 22:08:16 +00:00
}
2008-08-04 21:17:42 +00:00
2014-07-12 22:08:16 +00:00
$class = ( $section_name === $section ) ? ' class="current"' : '';
2008-08-04 21:17:42 +00:00
$href = add_query_arg( array('tab' => $tab, 'section' => $section_name) );
2014-03-16 18:28:17 +00:00
$href = esc_url( $href );
2012-01-08 05:39:49 +00:00
$san_section = esc_attr( $section_name );
2014-03-16 18:28:17 +00:00
echo "\t<a name='$san_section' href='$href' $class>$title</a>\n";
2008-08-04 21:17:42 +00:00
}
2014-03-16 18:28:17 +00:00
2008-08-04 21:17:42 +00:00
echo "</div>\n";
2014-03-16 18:28:17 +00:00
2008-08-04 21:17:42 +00:00
?>
2016-06-15 16:37:29 +00:00
<div id="<?php echo $_tab; ?>-content" class='<?php echo $_with_banner; ?>'>
2014-03-16 18:28:17 +00:00
<div class="fyi">
2008-08-04 21:17:42 +00:00
<ul>
2016-06-15 16:37:29 +00:00
<?php if ( ! empty( $api->version ) ) { ?>
<li><strong><?php _e( 'Version:' ); ?></strong> <?php echo $api->version; ?></li>
<?php } if ( ! empty( $api->author ) ) { ?>
<li><strong><?php _e( 'Author:' ); ?></strong> <?php echo links_add_target( $api->author, '_blank' ); ?></li>
<?php } if ( ! empty( $api->last_updated ) ) { ?>
<li><strong><?php _e( 'Last Updated:' ); ?></strong>
<?php
/* translators: %s: Time since the last update */
printf( __( '%s ago' ), human_time_diff( strtotime( $api->last_updated ) ) );
?>
</li>
<?php } if ( ! empty( $api->requires ) ) { ?>
<li>
<strong><?php _e( 'Requires WordPress Version:' ); ?></strong>
<?php
/* translators: %s: WordPress version */
printf( __( '%s or higher' ), $api->requires );
?>
</li>
<?php } if ( ! empty( $api->tested ) ) { ?>
<li><strong><?php _e( 'Compatible up to:' ); ?></strong> <?php echo $api->tested; ?></li>
2016-10-05 03:33:29 +00:00
<?php } if ( isset( $api->active_installs ) ) { ?>
2016-06-15 16:37:29 +00:00
<li><strong><?php _e( 'Active Installs:' ); ?></strong> <?php
if ( $api->active_installs >= 1000000 ) {
_ex( '1+ Million', 'Active plugin installs' );
2016-10-05 03:33:29 +00:00
} elseif ( 0 == $api->active_installs ) {
_ex( 'Less Than 10', 'Active plugin installs' );
2016-06-15 16:37:29 +00:00
} else {
echo number_format_i18n( $api->active_installs ) . '+';
}
?></li>
<?php } if ( ! empty( $api->slug ) && empty( $api->external ) ) { ?>
2016-10-26 12:18:06 +00:00
<li><a target="_blank" href="<?php echo __( 'https://wordpress.org/plugins/' ) . $api->slug; ?>/"><?php _e( 'WordPress.org Plugin Page »' ); ?></a></li>
2016-06-15 16:37:29 +00:00
<?php } if ( ! empty( $api->homepage ) ) { ?>
<li><a target="_blank" href="<?php echo esc_url( $api->homepage ); ?>"><?php _e( 'Plugin Homepage »' ); ?></a></li>
<?php } if ( ! empty( $api->donate_link ) && empty( $api->contributors ) ) { ?>
<li><a target="_blank" href="<?php echo esc_url( $api->donate_link ); ?>"><?php _e( 'Donate to this plugin »' ); ?></a></li>
<?php } ?>
2008-08-04 21:17:42 +00:00
</ul>
2014-07-12 22:08:16 +00:00
<?php if ( ! empty( $api->rating ) ) { ?>
2016-06-15 16:37:29 +00:00
<h3><?php _e( 'Average Rating' ); ?></h3>
<?php wp_star_rating( array( 'rating' => $api->rating, 'type' => 'percent', 'number' => $api->num_ratings ) ); ?>
<p aria-hidden="true" class="fyi-description"><?php printf( _n( '(based on %s rating)', '(based on %s ratings)', $api->num_ratings ), number_format_i18n( $api->num_ratings ) ); ?></p>
2014-07-12 22:08:16 +00:00
<?php }
2016-02-22 23:18:29 +00:00
if ( ! empty( $api->ratings ) && array_sum( (array) $api->ratings ) > 0 ) { ?>
<h3><?php _e( 'Reviews' ); ?></h3>
<p class="fyi-description"><?php _e( 'Read all reviews on WordPress.org or write your own!' ); ?></p>
<?php
2015-08-25 20:28:22 +00:00
foreach ( $api->ratings as $key => $ratecount ) {
2014-07-17 09:14:16 +00:00
// Avoid div-by-zero.
2014-07-09 17:28:17 +00:00
$_rating = $api->num_ratings ? ( $ratecount / $api->num_ratings ) : 0;
2016-04-02 11:12:26 +00:00
/* translators: 1: number of stars (used to determine singular/plural), 2: number of reviews */
2016-04-02 11:17:26 +00:00
$aria_label = esc_attr( sprintf( _n( 'Reviews with %1$d star: %2$s. Opens in a new window.', 'Reviews with %1$d stars: %2$s. Opens in a new window.', $key ),
2016-02-22 23:18:29 +00:00
$key,
number_format_i18n( $ratecount )
) );
2014-07-09 17:28:17 +00:00
?>
<div class="counter-container">
2016-06-15 16:37:29 +00:00
<span class="counter-label"><a href="https://wordpress.org/support/view/plugin-reviews/<?php echo $api->slug; ?>?filter=<?php echo $key; ?>"
target="_blank" aria-label="<?php echo $aria_label; ?>"><?php printf( _n( '%d star', '%d stars', $key ), $key ); ?></a></span>
<span class="counter-back">
<span class="counter-bar" style="width: <?php echo 92 * $_rating; ?>px;"></span>
</span>
2016-02-22 23:18:29 +00:00
<span class="counter-count" aria-hidden="true"><?php echo number_format_i18n( $ratecount ); ?></span>
2014-07-09 17:28:17 +00:00
</div>
2014-07-12 22:08:16 +00:00
<?php
2014-07-09 17:28:17 +00:00
}
}
2014-07-12 22:08:16 +00:00
if ( ! empty( $api->contributors ) ) { ?>
<h3><?php _e( 'Contributors' ); ?></h3>
2014-07-09 17:28:17 +00:00
<ul class="contributors">
<?php
foreach ( (array) $api->contributors as $contrib_username => $contrib_profile ) {
2014-07-12 22:08:16 +00:00
if ( empty( $contrib_username ) && empty( $contrib_profile ) ) {
2014-07-09 17:28:17 +00:00
continue;
2014-07-12 22:08:16 +00:00
}
if ( empty( $contrib_username ) ) {
2014-07-09 17:28:17 +00:00
$contrib_username = preg_replace( '/^.+\/(.+)\/?$/', '\1', $contrib_profile );
2014-07-12 22:08:16 +00:00
}
2014-07-09 17:28:17 +00:00
$contrib_username = sanitize_user( $contrib_username );
2014-07-12 22:08:16 +00:00
if ( empty( $contrib_profile ) ) {
2015-11-07 16:12:27 +00:00
echo "<li><img src='https://wordpress.org/grav-redirect.php?user={$contrib_username}&s=36' width='18' height='18' alt='' />{$contrib_username}</li>";
2014-07-12 22:08:16 +00:00
} else {
2015-11-07 16:12:27 +00:00
echo "<li><a href='{$contrib_profile}' target='_blank'><img src='https://wordpress.org/grav-redirect.php?user={$contrib_username}&s=36' width='18' height='18' alt='' />{$contrib_username}</a></li>";
2014-07-12 22:08:16 +00:00
}
2014-07-09 17:28:17 +00:00
}
?>
</ul>
2014-07-12 22:08:16 +00:00
<?php if ( ! empty( $api->donate_link ) ) { ?>
<a target="_blank" href="<?php echo esc_url( $api->donate_link ); ?>"><?php _e( 'Donate to this plugin »' ); ?></a>
<?php } ?>
<?php } ?>
2008-08-04 21:17:42 +00:00
</div>
2008-08-05 17:06:42 +00:00
<div id="section-holder" class="wrap">
2008-10-13 23:39:56 +00:00
<?php
2016-08-31 05:49:37 +00:00
$wp_version = get_bloginfo( 'version' );
if ( ! empty( $api->tested ) && version_compare( substr( $wp_version, 0, strlen( $api->tested ) ), $api->tested, '>' ) ) {
2016-06-15 16:37:29 +00:00
echo '<div class="notice notice-warning notice-alt"><p>' . __( '<strong>Warning:</strong> This plugin has <strong>not been tested</strong> with your current version of WordPress.' ) . '</p></div>';
2016-08-31 05:49:37 +00:00
} elseif ( ! empty( $api->requires ) && version_compare( substr( $wp_version, 0, strlen( $api->requires ) ), $api->requires, '<' ) ) {
2016-06-15 16:37:29 +00:00
echo '<div class="notice notice-warning notice-alt"><p>' . __( '<strong>Warning:</strong> This plugin has <strong>not been marked as compatible</strong> with your version of WordPress.' ) . '</p></div>';
}
2009-03-10 18:31:55 +00:00
2016-06-15 16:37:29 +00:00
foreach ( (array) $api->sections as $section_name => $content ) {
$content = links_add_base_url( $content, 'https://wordpress.org/plugins/' . $api->slug . '/' );
$content = links_add_target( $content, '_blank' );
2008-08-09 05:36:14 +00:00
2016-06-15 16:37:29 +00:00
$san_section = esc_attr( $section_name );
2008-08-09 05:36:14 +00:00
2016-06-15 16:37:29 +00:00
$display = ( $section_name === $section ) ? 'block' : 'none';
2008-08-09 05:36:14 +00:00
2016-06-15 16:37:29 +00:00
echo "\t<div id='section-{$san_section}' class='section' style='display: {$display};'>\n";
echo $content;
echo "\t</div>\n";
}
2008-08-04 21:17:42 +00:00
echo "</div>\n";
2014-03-16 18:28:17 +00:00
echo "</div>\n";
2014-08-12 23:02:16 +00:00
echo "</div>\n"; // #plugin-information-scrollable
2014-03-16 18:28:17 +00:00
echo "<div id='$tab-footer'>\n";
2014-07-12 22:08:16 +00:00
if ( ! empty( $api->download_link ) && ( current_user_can( 'install_plugins' ) || current_user_can( 'update_plugins' ) ) ) {
$status = install_plugin_install_status( $api );
2014-03-16 18:28:17 +00:00
switch ( $status['status'] ) {
case 'install':
2014-07-12 22:08:16 +00:00
if ( $status['url'] ) {
2016-06-15 16:37:29 +00:00
echo '<a data-slug="' . esc_attr( $api->slug ) . '" id="plugin_install_from_iframe" class="button button-primary right" href="' . $status['url'] . '" target="_parent">' . __( 'Install Now' ) . '</a>';
2014-07-12 22:08:16 +00:00
}
2014-03-16 18:28:17 +00:00
break;
case 'update_available':
2014-07-12 22:08:16 +00:00
if ( $status['url'] ) {
2016-01-08 17:48:28 +00:00
echo '<a data-slug="' . esc_attr( $api->slug ) . '" data-plugin="' . esc_attr( $status['file'] ) . '" id="plugin_update_from_iframe" class="button button-primary right" href="' . $status['url'] . '" target="_parent">' . __( 'Install Update Now' ) .'</a>';
2014-07-12 22:08:16 +00:00
}
2014-03-16 18:28:17 +00:00
break;
case 'newer_installed':
2016-06-15 16:37:29 +00:00
/* translators: %s: Plugin version */
2014-07-12 22:08:16 +00:00
echo '<a class="button button-primary right disabled">' . sprintf( __( 'Newer Version (%s) Installed'), $status['version'] ) . '</a>';
2014-03-16 18:28:17 +00:00
break;
case 'latest_installed':
2014-07-12 22:08:16 +00:00
echo '<a class="button button-primary right disabled">' . __( 'Latest Version Installed' ) . '</a>';
2014-03-16 18:28:17 +00:00
break;
}
}
echo "</div>\n";
2008-08-05 17:06:42 +00:00
2008-10-13 23:39:56 +00:00
iframe_footer();
2008-08-04 21:17:42 +00:00
exit;
}