X-Git-Url: https://scripts.mit.edu/gitweb/autoinstalls/wordpress.git/blobdiff_plain/2329f698283944696a7076258cf816545970bb47..3194d1bb103c2d8db4f44feeced5e58ee2756658:/wp-admin/includes/plugin-install.php diff --git a/wp-admin/includes/plugin-install.php b/wp-admin/includes/plugin-install.php index 356fff6d..bb450e12 100644 --- a/wp-admin/includes/plugin-install.php +++ b/wp-admin/includes/plugin-install.php @@ -7,37 +7,115 @@ */ /** - * Retrieve plugin installer pages from WordPress Plugins API. + * Retrieves plugin installer pages from the WordPress.org Plugins API. * * 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 - * offer more choices. This is very powerful and must be used with care, when + * offer more choices. This is very powerful and must be used with care when * overriding the filters. * - * The first filter, 'plugins_api_args', is for the args and gives the action as - * the second parameter. The hook for 'plugins_api_args' must ensure that an - * object is returned. + * 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. * - * The second filter, 'plugins_api', is the result that would be returned. + * The second filter, {@see 'plugins_api'}, allows a plugin to override the WordPress.org + * Plugin Install API entirely. If `$action` is 'query_plugins' or 'plugin_information', + * an object MUST be passed. If `$action` is 'hot_tags` or 'hot_categories', an array MUST + * 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. + * + * 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 | * * @since 2.7.0 * - * @param string $action - * @param array|object $args Optional. Arguments to serialize for the Plugin Info API. - * @return object plugins_api response object on success, WP_Error on failure. + * @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. + * + * @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 { + * 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. + * } + * } + * @return object|array|WP_Error Response object or array on success, WP_Error on failure. See the + * {@link https://developer.wordpress.org/reference/functions/plugins_api/ function reference article} + * for more information on the make-up of possible return values depending on the value of `$action`. */ -function plugins_api($action, $args = null) { +function plugins_api( $action, $args = array() ) { - if ( is_array($args) ) - $args = (object)$args; + if ( is_array( $args ) ) { + $args = (object) $args; + } - if ( !isset($args->per_page) ) + if ( ! isset( $args->per_page ) ) { $args->per_page = 24; + } + + if ( ! isset( $args->locale ) ) { + $args->locale = get_locale(); + } /** - * Override the Plugin Install API arguments. + * Filter the WordPress.org Plugin Install API arguments. * - * Please ensure that an object is returned. + * Important: An object MUST be returned to this filter. * * @since 2.7.0 * @@ -47,15 +125,18 @@ function plugins_api($action, $args = null) { $args = apply_filters( 'plugins_api_args', $args, $action ); /** - * Allows a plugin to override the WordPress.org Plugin Install API entirely. + * Filter the response for the current WordPress.org Plugin Install API request. + * + * Passing a non-false value will effectively short-circuit the WordPress.org API request. * - * Please ensure that an object is returned. + * If `$action` is 'query_plugins' or 'plugin_information', an object MUST be passed. + * If `$action` is 'hot_tags` or 'hot_categories', an array should be passed. * * @since 2.7.0 * - * @param bool|object $result The result object. Default false. - * @param string $action The type of information being requested from the Plugin Install API. - * @param object $args Plugin API arguments. + * @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. */ $res = apply_filters( 'plugins_api', false, $action, $args ); @@ -64,18 +145,18 @@ function plugins_api($action, $args = null) { if ( $ssl = wp_http_supports( array( 'ssl' ) ) ) $url = set_url_scheme( $url, 'https' ); - $args = array( + $http_args = array( 'timeout' => 15, 'body' => array( 'action' => $action, 'request' => serialize( $args ) ) ); - $request = wp_remote_post( $url, $args ); + $request = wp_remote_post( $url, $http_args ); if ( $ssl && is_wp_error( $request ) ) { trigger_error( __( '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 support forums.' ) . ' ' . __( '(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 ); - $request = wp_remote_post( $http_url, $args ); + $request = wp_remote_post( $http_url, $http_args ); } if ( is_wp_error($request) ) { @@ -124,13 +205,16 @@ function install_popular_tags( $args = array() ) { return $tags; } +/** + * @since 2.7.0 + */ function install_dashboard() { ?>

WordPress Plugin Directory or upload a plugin in .zip format via this page.' ), 'https://wordpress.org/plugins/', self_admin_url( 'plugin-install.php?tab=upload' ) ); ?>

-

+

esc_url( self_admin_url('plugin-install.php?tab=search&type=tag&s=' . urlencode($tag['name'])) ), - 'name' => $tag['name'], - 'id' => sanitize_title_with_dashes($tag['name']), - 'count' => $tag['count'] ); + 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; + } echo wp_generate_tag_cloud($tags, array( 'single_text' => __('%s plugin'), 'multiple_text' => __('%s plugins') ) ); } echo '


'; } -add_action( 'install_plugins_featured', 'install_dashboard' ); /** * Display search form for searching plugins. * * @since 2.7.0 + * + * @param bool $type_selector */ function install_search_form( $type_selector = true ) { $type = isset($_REQUEST['type']) ? wp_unslash( $_REQUEST['type'] ) : 'term'; @@ -170,7 +260,7 @@ function install_search_form( $type_selector = true ) { $input_attrs = 'class="wp-filter-search" placeholder="' . esc_attr__( 'Search Plugins' ) . '" '; } - ?>
+ ?>

@@ -231,30 +318,38 @@ function install_plugins_favorites_form() { * Display plugin content based on plugin list. * * @since 2.7.0 + * + * @global WP_List_Table $wp_list_table */ function display_plugins_table() { global $wp_list_table; - if ( current_filter() == 'install_plugins_favorites' && empty( $_GET['user'] ) && ! get_user_option( 'wporg_favorites' ) ) { - return; + switch ( current_filter() ) { + case 'install_plugins_favorites' : + if ( empty( $_GET['user'] ) && ! get_user_option( 'wporg_favorites' ) ) { + return; + } + break; + case 'install_plugins_recommended' : + echo '

' . __( 'These suggestions are based on the plugins you and other users have installed.' ) . '

'; + break; } ?> - + display(); ?>
slug), 'install-plugin_' . $api->slug); } else { $key = array_keys( $installed_plugin ); - $key = array_shift( $key ); //Use the first plugin regardless of the name, Could have issues for multiple-plugins in one directory if they share different version numbers + $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 + $update_file = $api->slug . '/' . $key; if ( version_compare($api->version, $installed_plugin[ $key ]['Version'], '=') ){ $status = 'latest_installed'; } elseif ( version_compare($api->version, $installed_plugin[ $key ]['Version'], '<') ) { @@ -315,21 +412,34 @@ function install_plugin_install_status($api, $loop = false) { if ( isset($_GET['from']) ) $url .= '&from=' . urlencode( wp_unslash( $_GET['from'] ) ); - return compact('status', 'url', 'version'); + $file = $update_file; + return compact( 'status', 'url', 'version', 'file' ); } /** * Display plugin information in dialog box form. * * @since 2.7.0 + * + * @global string $tab + * @global string $wp_version */ function install_plugin_information() { global $tab; + if ( empty( $_REQUEST['plugin'] ) ) { + return; + } + $api = plugins_api( 'plugin_information', array( 'slug' => wp_unslash( $_REQUEST['plugin'] ), 'is_ssl' => is_ssl(), - 'fields' => array( 'banners' => true, 'reviews' => true ) + 'fields' => array( + 'banners' => true, + 'reviews' => true, + 'downloaded' => false, + 'active_installs' => true + ) ) ); if ( is_wp_error( $api ) ) { @@ -372,7 +482,7 @@ function install_plugin_information() { $section = isset( $_REQUEST['section'] ) ? wp_unslash( $_REQUEST['section'] ) : 'description'; // Default to the Description tab, Do not translate, API returns English. if ( empty( $section ) || ! isset( $api->sections[ $section ] ) ) { $section_titles = array_keys( (array) $api->sections ); - $section = array_shift( $section_titles ); + $section = reset( $section_titles ); } iframe_header( __( 'Plugin Install' ) ); @@ -421,6 +531,12 @@ function install_plugin_information() { echo "\n"; + $date_format = __( 'M j, Y @ H:i' ); + + if ( ! empty( $api->last_updated ) ) { + $last_updated_timestamp = strtotime( $api->last_updated ); + } + ?>
@@ -430,15 +546,21 @@ function install_plugin_information() { author ) ) { ?>
  • author, '_blank' ); ?>
  • last_updated ) ) { ?> -
  • - last_updated ) ) ); ?> +
  • +
  • requires ) ) { ?>
  • requires ); ?>
  • tested ) ) { ?>
  • tested; ?>
  • - downloaded ) ) { ?> -
  • downloaded ), number_format_i18n( $api->downloaded ) ); ?>
  • + active_installs ) ) { ?> +
  • active_installs >= 1000000 ) { + _ex( '1+ Million', 'Active plugin installs' ); + } else { + echo number_format_i18n( $api->active_installs ) . '+'; + } + ?>
  • slug ) && empty( $api->external ) ) { ?>
  • homepage ) ) { ?> @@ -454,18 +576,17 @@ function install_plugin_information() { ratings ) && array_sum( (array) $api->ratings ) > 0 ) { - foreach( $api->ratings as $key => $ratecount ) { + foreach ( $api->ratings as $key => $ratecount ) { // Avoid div-by-zero. $_rating = $api->num_ratings ? ( $ratecount / $api->num_ratings ) : 0; ?>
    - - - - - - + + + +
    {$contrib_username}"; + echo "
  • {$contrib_username}
  • "; } else { - echo "
  • {$contrib_username}
  • "; + echo "
  • {$contrib_username}
  • "; } } ?> @@ -499,9 +620,9 @@ function install_plugin_information() {
    tested ) && version_compare( substr( $GLOBALS['wp_version'], 0, strlen( $api->tested ) ), $api->tested, '>' ) ) { - echo '

    ' . __('Warning: This plugin has not been tested with your current version of WordPress.') . '

    '; - } else if ( ! empty( $api->requires ) && version_compare( substr( $GLOBALS['wp_version'], 0, strlen( $api->requires ) ), $api->requires, '<' ) ) { - echo '

    ' . __('Warning: This plugin has not been marked as compatible with your version of WordPress.') . '

    '; + echo '

    ' . __( 'Warning: This plugin has not been tested with your current version of WordPress.' ) . '

    '; + } elseif ( ! empty( $api->requires ) && version_compare( substr( $GLOBALS['wp_version'], 0, strlen( $api->requires ) ), $api->requires, '<' ) ) { + echo '

    ' . __( 'Warning: This plugin has not been marked as compatible with your version of WordPress.' ) . '

    '; } foreach ( (array) $api->sections as $section_name => $content ) { @@ -530,7 +651,7 @@ function install_plugin_information() { break; case 'update_available': if ( $status['url'] ) { - echo '' . __( 'Install Update Now' ) .''; + echo '' . __( 'Install Update Now' ) .''; } break; case 'newer_installed': @@ -546,4 +667,3 @@ function install_plugin_information() { iframe_footer(); exit; } -add_action('install_plugins_pre_plugin-information', 'install_plugin_information');