plugins_api

The timeline below displays how wordpress function plugins_api has changed across different WordPress versions. If a version is not listed, refer to the next available version below.

WordPress Version: 5.9

/**
 * WordPress Plugin Install Administration API
 *
 * @package WordPress
 * @subpackage Administration
 */
/**
 * 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
 * overriding the filters.
 *
 * 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, {@see 'plugins_api'}, allows a plugin to override the WordPress.org
 * Plugin Installation 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 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 $requires_php      Whether to return the required PHP 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 installations. 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 = array())
{
    // Include an unmodified $wp_version.
    require ABSPATH . WPINC . '/version.php';
    if (is_array($args)) {
        $args = (object) $args;
    }
    if ('query_plugins' === $action) {
        if (!isset($args->per_page)) {
            $args->per_page = 24;
        }
    }
    if (!isset($args->locale)) {
        $args->locale = get_user_locale();
    }
    if (!isset($args->wp_version)) {
        $args->wp_version = substr($wp_version, 0, 3);
        // x.y
    }
    /**
     * Filters the WordPress.org Plugin Installation API arguments.
     *
     * Important: An object MUST be returned to this filter.
     *
     * @since 2.7.0
     *
     * @param object $args   Plugin API arguments.
     * @param string $action The type of information being requested from the Plugin Installation API.
     */
    $args = apply_filters('plugins_api_args', $args, $action);
    /**
     * Filters the response for the current WordPress.org Plugin Installation API request.
     *
     * Returning a non-false value will effectively short-circuit the WordPress.org API request.
     *
     * 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 false|object|array $result The result object or array. Default false.
     * @param string             $action The type of information being requested from the Plugin Installation API.
     * @param object             $args   Plugin API arguments.
     */
    $res = apply_filters('plugins_api', false, $action, $args);
    if (false === $res) {
        $url = 'http://api.wordpress.org/plugins/info/1.2/';
        $url = add_query_arg(array('action' => $action, 'request' => $args), $url);
        $http_url = $url;
        $ssl = wp_http_supports(array('ssl'));
        if ($ssl) {
            $url = set_url_scheme($url, 'https');
        }
        $http_args = array('timeout' => 15, 'user-agent' => 'WordPress/' . $wp_version . '; ' . home_url('/'));
        $request = wp_remote_get($url, $http_args);
        if ($ssl && is_wp_error($request)) {
            if (!wp_is_json_request()) {
                trigger_error(sprintf(
                    /* translators: %s: Support forums URL. */
                    __('An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.'),
                    __('https://wordpress.org/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_get($http_url, $http_args);
        }
        if (is_wp_error($request)) {
            $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&#8217;s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.'),
                __('https://wordpress.org/support/forums/')
            ), $request->get_error_message());
        } else {
            $res = json_decode(wp_remote_retrieve_body($request), true);
            if (is_array($res)) {
                // Object casting is required in order to match the info/1.0 format.
                $res = (object) $res;
            } elseif (null === $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&#8217;s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.'),
                    __('https://wordpress.org/support/forums/')
                ), wp_remote_retrieve_body($request));
            }
            if (isset($res->error)) {
                $res = new WP_Error('plugins_api_failed', $res->error);
            }
        }
    } elseif (!is_wp_error($res)) {
        $res->external = true;
    }
    /**
     * Filters the Plugin Installation API response results.
     *
     * @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 Installation API.
     * @param object          $args   Plugin API arguments.
     */
    return apply_filters('plugins_api_result', $res, $action, $args);
}

WordPress Version: 5.5

/**
 * WordPress Plugin Install Administration API
 *
 * @package WordPress
 * @subpackage Administration
 */
/**
 * 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
 * overriding the filters.
 *
 * 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, {@see 'plugins_api'}, allows a plugin to override the WordPress.org
 * Plugin Installation 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 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 $requires_php      Whether to return the required PHP 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 installations. 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 = array())
{
    // Include an unmodified $wp_version.
    require ABSPATH . WPINC . '/version.php';
    if (is_array($args)) {
        $args = (object) $args;
    }
    if ('query_plugins' === $action) {
        if (!isset($args->per_page)) {
            $args->per_page = 24;
        }
    }
    if (!isset($args->locale)) {
        $args->locale = get_user_locale();
    }
    if (!isset($args->wp_version)) {
        $args->wp_version = substr($wp_version, 0, 3);
        // x.y
    }
    /**
     * Filters the WordPress.org Plugin Installation API arguments.
     *
     * Important: An object MUST be returned to this filter.
     *
     * @since 2.7.0
     *
     * @param object $args   Plugin API arguments.
     * @param string $action The type of information being requested from the Plugin Installation API.
     */
    $args = apply_filters('plugins_api_args', $args, $action);
    /**
     * Filters the response for the current WordPress.org Plugin Installation API request.
     *
     * Passing a non-false value will effectively short-circuit the WordPress.org API request.
     *
     * 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 false|object|array $result The result object or array. Default false.
     * @param string             $action The type of information being requested from the Plugin Installation API.
     * @param object             $args   Plugin API arguments.
     */
    $res = apply_filters('plugins_api', false, $action, $args);
    if (false === $res) {
        $url = 'http://api.wordpress.org/plugins/info/1.2/';
        $url = add_query_arg(array('action' => $action, 'request' => $args), $url);
        $http_url = $url;
        $ssl = wp_http_supports(array('ssl'));
        if ($ssl) {
            $url = set_url_scheme($url, 'https');
        }
        $http_args = array('timeout' => 15, 'user-agent' => 'WordPress/' . $wp_version . '; ' . home_url('/'));
        $request = wp_remote_get($url, $http_args);
        if ($ssl && is_wp_error($request)) {
            if (!wp_is_json_request()) {
                trigger_error(sprintf(
                    /* translators: %s: Support forums URL. */
                    __('An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.'),
                    __('https://wordpress.org/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_get($http_url, $http_args);
        }
        if (is_wp_error($request)) {
            $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&#8217;s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.'),
                __('https://wordpress.org/support/forums/')
            ), $request->get_error_message());
        } else {
            $res = json_decode(wp_remote_retrieve_body($request), true);
            if (is_array($res)) {
                // Object casting is required in order to match the info/1.0 format.
                $res = (object) $res;
            } elseif (null === $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&#8217;s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.'),
                    __('https://wordpress.org/support/forums/')
                ), wp_remote_retrieve_body($request));
            }
            if (isset($res->error)) {
                $res = new WP_Error('plugins_api_failed', $res->error);
            }
        }
    } elseif (!is_wp_error($res)) {
        $res->external = true;
    }
    /**
     * Filters the Plugin Installation API response results.
     *
     * @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 Installation API.
     * @param object          $args   Plugin API arguments.
     */
    return apply_filters('plugins_api_result', $res, $action, $args);
}

WordPress Version: 5.4

/**
 * WordPress Plugin Install Administration API
 *
 * @package WordPress
 * @subpackage Administration
 */
/**
 * 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
 * overriding the filters.
 *
 * 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, {@see 'plugins_api'}, allows a plugin to override the WordPress.org
 * Plugin Installation 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 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 $requires_php      Whether to return the required PHP 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 installations. 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 = array())
{
    // Include an unmodified $wp_version.
    require ABSPATH . WPINC . '/version.php';
    if (is_array($args)) {
        $args = (object) $args;
    }
    if ('query_plugins' == $action) {
        if (!isset($args->per_page)) {
            $args->per_page = 24;
        }
    }
    if (!isset($args->locale)) {
        $args->locale = get_user_locale();
    }
    if (!isset($args->wp_version)) {
        $args->wp_version = substr($wp_version, 0, 3);
        // x.y
    }
    /**
     * Filters the WordPress.org Plugin Installation API arguments.
     *
     * Important: An object MUST be returned to this filter.
     *
     * @since 2.7.0
     *
     * @param object $args   Plugin API arguments.
     * @param string $action The type of information being requested from the Plugin Installation API.
     */
    $args = apply_filters('plugins_api_args', $args, $action);
    /**
     * Filters the response for the current WordPress.org Plugin Installation API request.
     *
     * Passing a non-false value will effectively short-circuit the WordPress.org API request.
     *
     * 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 false|object|array $result The result object or array. Default false.
     * @param string             $action The type of information being requested from the Plugin Installation API.
     * @param object             $args   Plugin API arguments.
     */
    $res = apply_filters('plugins_api', false, $action, $args);
    if (false === $res) {
        $url = 'http://api.wordpress.org/plugins/info/1.2/';
        $url = add_query_arg(array('action' => $action, 'request' => $args), $url);
        $http_url = $url;
        $ssl = wp_http_supports(array('ssl'));
        if ($ssl) {
            $url = set_url_scheme($url, 'https');
        }
        $http_args = array('timeout' => 15, 'user-agent' => 'WordPress/' . $wp_version . '; ' . home_url('/'));
        $request = wp_remote_get($url, $http_args);
        if ($ssl && is_wp_error($request)) {
            trigger_error(sprintf(
                /* translators: %s: Support forums URL. */
                __('An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.'),
                __('https://wordpress.org/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_get($http_url, $http_args);
        }
        if (is_wp_error($request)) {
            $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&#8217;s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.'),
                __('https://wordpress.org/support/forums/')
            ), $request->get_error_message());
        } else {
            $res = json_decode(wp_remote_retrieve_body($request), true);
            if (is_array($res)) {
                // Object casting is required in order to match the info/1.0 format.
                $res = (object) $res;
            } elseif (null === $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&#8217;s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.'),
                    __('https://wordpress.org/support/forums/')
                ), wp_remote_retrieve_body($request));
            }
            if (isset($res->error)) {
                $res = new WP_Error('plugins_api_failed', $res->error);
            }
        }
    } elseif (!is_wp_error($res)) {
        $res->external = true;
    }
    /**
     * Filters the Plugin Installation API response results.
     *
     * @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 Installation API.
     * @param object          $args   Plugin API arguments.
     */
    return apply_filters('plugins_api_result', $res, $action, $args);
}

WordPress Version: 5.3

/**
 * WordPress Plugin Install Administration API
 *
 * @package WordPress
 * @subpackage Administration
 */
/**
 * 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
 * overriding the filters.
 *
 * 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, {@see 'plugins_api'}, allows a plugin to override the WordPress.org
 * Plugin Installation 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 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 $requires_php      Whether to return the required PHP 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 installations. 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 = array())
{
    // include an unmodified $wp_version
    include ABSPATH . WPINC . '/version.php';
    if (is_array($args)) {
        $args = (object) $args;
    }
    if ('query_plugins' == $action) {
        if (!isset($args->per_page)) {
            $args->per_page = 24;
        }
    }
    if (!isset($args->locale)) {
        $args->locale = get_user_locale();
    }
    if (!isset($args->wp_version)) {
        $args->wp_version = substr($wp_version, 0, 3);
        // X.y
    }
    /**
     * Filters the WordPress.org Plugin Installation API arguments.
     *
     * Important: An object MUST be returned to this filter.
     *
     * @since 2.7.0
     *
     * @param object $args   Plugin API arguments.
     * @param string $action The type of information being requested from the Plugin Installation API.
     */
    $args = apply_filters('plugins_api_args', $args, $action);
    /**
     * Filters the response for the current WordPress.org Plugin Installation API request.
     *
     * Passing a non-false value will effectively short-circuit the WordPress.org API request.
     *
     * 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 false|object|array $result The result object or array. Default false.
     * @param string             $action The type of information being requested from the Plugin Installation API.
     * @param object             $args   Plugin API arguments.
     */
    $res = apply_filters('plugins_api', false, $action, $args);
    if (false === $res) {
        $url = 'http://api.wordpress.org/plugins/info/1.2/';
        $url = add_query_arg(array('action' => $action, 'request' => $args), $url);
        $http_url = $url;
        $ssl = wp_http_supports(array('ssl'));
        if ($ssl) {
            $url = set_url_scheme($url, 'https');
        }
        $http_args = array('timeout' => 15, 'user-agent' => 'WordPress/' . $wp_version . '; ' . home_url('/'));
        $request = wp_remote_get($url, $http_args);
        if ($ssl && is_wp_error($request)) {
            trigger_error(sprintf(
                /* translators: %s: Support forums URL. */
                __('An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.'),
                __('https://wordpress.org/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_get($http_url, $http_args);
        }
        if (is_wp_error($request)) {
            $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&#8217;s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.'),
                __('https://wordpress.org/support/forums/')
            ), $request->get_error_message());
        } else {
            $res = json_decode(wp_remote_retrieve_body($request), true);
            if (is_array($res)) {
                // Object casting is required in order to match the info/1.0 format.
                $res = (object) $res;
            } elseif (null === $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&#8217;s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.'),
                    __('https://wordpress.org/support/forums/')
                ), wp_remote_retrieve_body($request));
            }
            if (isset($res->error)) {
                $res = new WP_Error('plugins_api_failed', $res->error);
            }
        }
    } elseif (!is_wp_error($res)) {
        $res->external = true;
    }
    /**
     * Filters the Plugin Installation API response results.
     *
     * @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 Installation API.
     * @param object          $args   Plugin API arguments.
     */
    return apply_filters('plugins_api_result', $res, $action, $args);
}

WordPress Version: 5.1

/**
 * WordPress Plugin Install Administration API
 *
 * @package WordPress
 * @subpackage Administration
 */
/**
 * 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
 * overriding the filters.
 *
 * 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, {@see 'plugins_api'}, allows a plugin to override the WordPress.org
 * Plugin Installation 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 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 installations. 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 = array())
{
    // include an unmodified $wp_version
    include ABSPATH . WPINC . '/version.php';
    if (is_array($args)) {
        $args = (object) $args;
    }
    if ('query_plugins' == $action) {
        if (!isset($args->per_page)) {
            $args->per_page = 24;
        }
    }
    if (!isset($args->locale)) {
        $args->locale = get_user_locale();
    }
    if (!isset($args->wp_version)) {
        $args->wp_version = substr($wp_version, 0, 3);
        // X.y
    }
    /**
     * Filters the WordPress.org Plugin Installation API arguments.
     *
     * Important: An object MUST be returned to this filter.
     *
     * @since 2.7.0
     *
     * @param object $args   Plugin API arguments.
     * @param string $action The type of information being requested from the Plugin Installation API.
     */
    $args = apply_filters('plugins_api_args', $args, $action);
    /**
     * Filters the response for the current WordPress.org Plugin Installation API request.
     *
     * Passing a non-false value will effectively short-circuit the WordPress.org API request.
     *
     * 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 false|object|array $result The result object or array. Default false.
     * @param string             $action The type of information being requested from the Plugin Installation API.
     * @param object             $args   Plugin API arguments.
     */
    $res = apply_filters('plugins_api', false, $action, $args);
    if (false === $res) {
        $url = 'http://api.wordpress.org/plugins/info/1.2/';
        $url = add_query_arg(array('action' => $action, 'request' => $args), $url);
        $http_url = $url;
        if ($ssl = wp_http_supports(array('ssl'))) {
            $url = set_url_scheme($url, 'https');
        }
        $http_args = array('timeout' => 15, 'user-agent' => 'WordPress/' . $wp_version . '; ' . home_url('/'));
        $request = wp_remote_get($url, $http_args);
        if ($ssl && is_wp_error($request)) {
            trigger_error(sprintf(
                /* translators: %s: support forums URL */
                __('An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;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);
            $request = wp_remote_get($http_url, $http_args);
        }
        if (is_wp_error($request)) {
            $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&#8217;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());
        } else {
            $res = json_decode(wp_remote_retrieve_body($request), true);
            if (is_array($res)) {
                // Object casting is required in order to match the info/1.0 format.
                $res = (object) $res;
            } elseif (null === $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&#8217;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));
            }
            if (isset($res->error)) {
                $res = new WP_Error('plugins_api_failed', $res->error);
            }
        }
    } elseif (!is_wp_error($res)) {
        $res->external = true;
    }
    /**
     * Filters the Plugin Installation API response results.
     *
     * @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 Installation API.
     * @param object          $args   Plugin API arguments.
     */
    return apply_filters('plugins_api_result', $res, $action, $args);
}

WordPress Version: 4.9

/**
 * WordPress Plugin Install Administration API
 *
 * @package WordPress
 * @subpackage Administration
 */
/**
 * 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
 * overriding the filters.
 *
 * 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, {@see 'plugins_api'}, allows a plugin to override the WordPress.org
 * Plugin Installation 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 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 installations. 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 = array())
{
    if (is_array($args)) {
        $args = (object) $args;
    }
    if (!isset($args->per_page)) {
        $args->per_page = 24;
    }
    if (!isset($args->locale)) {
        $args->locale = get_user_locale();
    }
    /**
     * Filters the WordPress.org Plugin Installation API arguments.
     *
     * Important: An object MUST be returned to this filter.
     *
     * @since 2.7.0
     *
     * @param object $args   Plugin API arguments.
     * @param string $action The type of information being requested from the Plugin Installation API.
     */
    $args = apply_filters('plugins_api_args', $args, $action);
    /**
     * Filters the response for the current WordPress.org Plugin Installation API request.
     *
     * Passing a non-false value will effectively short-circuit the WordPress.org API request.
     *
     * 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 false|object|array $result The result object or array. Default false.
     * @param string             $action The type of information being requested from the Plugin Installation API.
     * @param object             $args   Plugin API arguments.
     */
    $res = apply_filters('plugins_api', false, $action, $args);
    if (false === $res) {
        // include an unmodified $wp_version
        include ABSPATH . WPINC . '/version.php';
        $url = $http_url = 'http://api.wordpress.org/plugins/info/1.0/';
        if ($ssl = wp_http_supports(array('ssl'))) {
            $url = set_url_scheme($url, 'https');
        }
        $http_args = array('timeout' => 15, 'user-agent' => 'WordPress/' . $wp_version . '; ' . home_url('/'), 'body' => array('action' => $action, 'request' => serialize($args)));
        $request = wp_remote_post($url, $http_args);
        if ($ssl && is_wp_error($request)) {
            trigger_error(sprintf(
                /* translators: %s: support forums URL */
                __('An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;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);
            $request = wp_remote_post($http_url, $http_args);
        }
        if (is_wp_error($request)) {
            $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&#8217;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());
        } else {
            $res = maybe_unserialize(wp_remote_retrieve_body($request));
            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&#8217;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));
            }
        }
    } elseif (!is_wp_error($res)) {
        $res->external = true;
    }
    /**
     * Filters the Plugin Installation API response results.
     *
     * @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 Installation API.
     * @param object          $args   Plugin API arguments.
     */
    return apply_filters('plugins_api_result', $res, $action, $args);
}

WordPress Version: 4.7

/**
 * WordPress Plugin Install Administration API
 *
 * @package WordPress
 * @subpackage Administration
 */
/**
 * 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
 * overriding the filters.
 *
 * 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, {@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 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 = array())
{
    if (is_array($args)) {
        $args = (object) $args;
    }
    if (!isset($args->per_page)) {
        $args->per_page = 24;
    }
    if (!isset($args->locale)) {
        $args->locale = get_user_locale();
    }
    /**
     * Filters the WordPress.org Plugin Install API arguments.
     *
     * Important: An object MUST be returned to this filter.
     *
     * @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);
    /**
     * Filters 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.
     *
     * 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 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);
    if (false === $res) {
        $url = $http_url = 'http://api.wordpress.org/plugins/info/1.0/';
        if ($ssl = wp_http_supports(array('ssl'))) {
            $url = set_url_scheme($url, 'https');
        }
        $http_args = array('timeout' => 15, 'body' => array('action' => $action, 'request' => serialize($args)));
        $request = wp_remote_post($url, $http_args);
        if ($ssl && is_wp_error($request)) {
            trigger_error(sprintf(
                /* translators: %s: support forums URL */
                __('An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;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);
            $request = wp_remote_post($http_url, $http_args);
        }
        if (is_wp_error($request)) {
            $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&#8217;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());
        } else {
            $res = maybe_unserialize(wp_remote_retrieve_body($request));
            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&#8217;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));
            }
        }
    } elseif (!is_wp_error($res)) {
        $res->external = true;
    }
    /**
     * Filters the Plugin Install API response results.
     *
     * @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);
}

WordPress Version: 4.6

/**
 * WordPress Plugin Install Administration API
 *
 * @package WordPress
 * @subpackage Administration
 */
/**
 * 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
 * overriding the filters.
 *
 * 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, {@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 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 = array())
{
    if (is_array($args)) {
        $args = (object) $args;
    }
    if (!isset($args->per_page)) {
        $args->per_page = 24;
    }
    if (!isset($args->locale)) {
        $args->locale = get_locale();
    }
    /**
     * Filters the WordPress.org Plugin Install API arguments.
     *
     * Important: An object MUST be returned to this filter.
     *
     * @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);
    /**
     * Filters 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.
     *
     * 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 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);
    if (false === $res) {
        $url = $http_url = 'http://api.wordpress.org/plugins/info/1.0/';
        if ($ssl = wp_http_supports(array('ssl'))) {
            $url = set_url_scheme($url, 'https');
        }
        $http_args = array('timeout' => 15, 'body' => array('action' => $action, 'request' => serialize($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&#8217;s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.') . ' ' . __('(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, $http_args);
        }
        if (is_wp_error($request)) {
            $res = new WP_Error('plugins_api_failed', __('An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.'), $request->get_error_message());
        } else {
            $res = maybe_unserialize(wp_remote_retrieve_body($request));
            if (!is_object($res) && !is_array($res)) {
                $res = new WP_Error('plugins_api_failed', __('An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.'), wp_remote_retrieve_body($request));
            }
        }
    } elseif (!is_wp_error($res)) {
        $res->external = true;
    }
    /**
     * Filters the Plugin Install API response results.
     *
     * @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);
}

WordPress Version: 4.4

/**
 * WordPress Plugin Install Administration API
 *
 * @package WordPress
 * @subpackage Administration
 */
/**
 * 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
 * overriding the filters.
 *
 * 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, {@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 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 = array())
{
    if (is_array($args)) {
        $args = (object) $args;
    }
    if (!isset($args->per_page)) {
        $args->per_page = 24;
    }
    if (!isset($args->locale)) {
        $args->locale = get_locale();
    }
    /**
     * Filter the WordPress.org Plugin Install API arguments.
     *
     * Important: An object MUST be returned to this filter.
     *
     * @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);
    /**
     * 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.
     *
     * 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 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);
    if (false === $res) {
        $url = $http_url = 'http://api.wordpress.org/plugins/info/1.0/';
        if ($ssl = wp_http_supports(array('ssl'))) {
            $url = set_url_scheme($url, 'https');
        }
        $http_args = array('timeout' => 15, 'body' => array('action' => $action, 'request' => serialize($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&#8217;s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.') . ' ' . __('(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, $http_args);
        }
        if (is_wp_error($request)) {
            $res = new WP_Error('plugins_api_failed', __('An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.'), $request->get_error_message());
        } else {
            $res = maybe_unserialize(wp_remote_retrieve_body($request));
            if (!is_object($res) && !is_array($res)) {
                $res = new WP_Error('plugins_api_failed', __('An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.'), wp_remote_retrieve_body($request));
            }
        }
    } elseif (!is_wp_error($res)) {
        $res->external = true;
    }
    /**
     * Filter the Plugin Install API response results.
     *
     * @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);
}

WordPress Version: 4.2

/**
 * WordPress Plugin Install Administration API
 *
 * @package WordPress
 * @subpackage Administration
 */
/**
 * Retrieve plugin installer pages from WordPress 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
 * 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 second filter, 'plugins_api', is the result that would be returned.
 *
 * @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.
 */
function plugins_api($action, $args = null)
{
    if (is_array($args)) {
        $args = (object) $args;
    }
    if (!isset($args->per_page)) {
        $args->per_page = 24;
    }
    if (!isset($args->locale)) {
        $args->locale = get_locale();
    }
    /**
     * Override the Plugin Install API arguments.
     *
     * Please ensure that an object is returned.
     *
     * @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);
    /**
     * Allows a plugin to override the WordPress.org Plugin Install API entirely.
     *
     * Please ensure that an object is returned.
     *
     * @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.
     */
    $res = apply_filters('plugins_api', false, $action, $args);
    if (false === $res) {
        $url = $http_url = 'http://api.wordpress.org/plugins/info/1.0/';
        if ($ssl = wp_http_supports(array('ssl'))) {
            $url = set_url_scheme($url, 'https');
        }
        $http_args = array('timeout' => 15, 'body' => array('action' => $action, 'request' => serialize($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&#8217;s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.') . ' ' . __('(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, $http_args);
        }
        if (is_wp_error($request)) {
            $res = new WP_Error('plugins_api_failed', __('An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.'), $request->get_error_message());
        } else {
            $res = maybe_unserialize(wp_remote_retrieve_body($request));
            if (!is_object($res) && !is_array($res)) {
                $res = new WP_Error('plugins_api_failed', __('An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.'), wp_remote_retrieve_body($request));
            }
        }
    } elseif (!is_wp_error($res)) {
        $res->external = true;
    }
    /**
     * Filter the Plugin Install API response results.
     *
     * @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);
}

WordPress Version: 4.1

/**
 * WordPress Plugin Install Administration API
 *
 * @package WordPress
 * @subpackage Administration
 */
/**
 * Retrieve plugin installer pages from WordPress 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
 * 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 second filter, 'plugins_api', is the result that would be returned.
 *
 * @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.
 */
function plugins_api($action, $args = null)
{
    if (is_array($args)) {
        $args = (object) $args;
    }
    if (!isset($args->per_page)) {
        $args->per_page = 24;
    }
    if (!isset($args->locale)) {
        $args->locale = get_locale();
    }
    /**
     * Override the Plugin Install API arguments.
     *
     * Please ensure that an object is returned.
     *
     * @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);
    /**
     * Allows a plugin to override the WordPress.org Plugin Install API entirely.
     *
     * Please ensure that an object is returned.
     *
     * @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.
     */
    $res = apply_filters('plugins_api', false, $action, $args);
    if (false === $res) {
        $url = $http_url = 'http://api.wordpress.org/plugins/info/1.0/';
        if ($ssl = wp_http_supports(array('ssl'))) {
            $url = set_url_scheme($url, 'https');
        }
        $args = array('timeout' => 15, 'body' => array('action' => $action, 'request' => serialize($args)));
        $request = wp_remote_post($url, $args);
        if ($ssl && is_wp_error($request)) {
            trigger_error(__('An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.') . ' ' . __('(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);
        }
        if (is_wp_error($request)) {
            $res = new WP_Error('plugins_api_failed', __('An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.'), $request->get_error_message());
        } else {
            $res = maybe_unserialize(wp_remote_retrieve_body($request));
            if (!is_object($res) && !is_array($res)) {
                $res = new WP_Error('plugins_api_failed', __('An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.'), wp_remote_retrieve_body($request));
            }
        }
    } elseif (!is_wp_error($res)) {
        $res->external = true;
    }
    /**
     * Filter the Plugin Install API response results.
     *
     * @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);
}

WordPress Version: 3.9

/**
 * WordPress Plugin Install Administration API
 *
 * @package WordPress
 * @subpackage Administration
 */
/**
 * Retrieve plugin installer pages from WordPress 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
 * 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 second filter, 'plugins_api', is the result that would be returned.
 *
 * @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.
 */
function plugins_api($action, $args = null)
{
    if (is_array($args)) {
        $args = (object) $args;
    }
    if (!isset($args->per_page)) {
        $args->per_page = 24;
    }
    /**
     * Override the Plugin Install API arguments.
     *
     * Please ensure that an object is returned.
     *
     * @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);
    /**
     * Allows a plugin to override the WordPress.org Plugin Install API entirely.
     *
     * Please ensure that an object is returned.
     *
     * @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.
     */
    $res = apply_filters('plugins_api', false, $action, $args);
    if (false === $res) {
        $url = $http_url = 'http://api.wordpress.org/plugins/info/1.0/';
        if ($ssl = wp_http_supports(array('ssl'))) {
            $url = set_url_scheme($url, 'https');
        }
        $args = array('timeout' => 15, 'body' => array('action' => $action, 'request' => serialize($args)));
        $request = wp_remote_post($url, $args);
        if ($ssl && is_wp_error($request)) {
            trigger_error(__('An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.') . ' ' . __('(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);
        }
        if (is_wp_error($request)) {
            $res = new WP_Error('plugins_api_failed', __('An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.'), $request->get_error_message());
        } else {
            $res = maybe_unserialize(wp_remote_retrieve_body($request));
            if (!is_object($res) && !is_array($res)) {
                $res = new WP_Error('plugins_api_failed', __('An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.'), wp_remote_retrieve_body($request));
            }
        }
    } elseif (!is_wp_error($res)) {
        $res->external = true;
    }
    /**
     * Filter the Plugin Install API response results.
     *
     * @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);
}

WordPress Version: 7.1

/**
 * WordPress Plugin Install Administration API
 *
 * @package WordPress
 * @subpackage Administration
 */
/**
 * Retrieve plugin installer pages from WordPress 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
 * 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 second filter, 'plugins_api', is the result that would be returned.
 *
 * @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.
 */
function plugins_api($action, $args = null)
{
    if (is_array($args)) {
        $args = (object) $args;
    }
    if (!isset($args->per_page)) {
        $args->per_page = 24;
    }
    /**
     * Override the Plugin Install API arguments.
     *
     * Please ensure that an object is returned.
     *
     * @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);
    /**
     * Allows a plugin to override the WordPress.org Plugin Install API entirely.
     *
     * Please ensure that an object is returned.
     *
     * @since 2.7.0
     *
     * @param bool|object         The result object. Default is 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);
    if (false === $res) {
        $url = $http_url = 'http://api.wordpress.org/plugins/info/1.0/';
        if ($ssl = wp_http_supports(array('ssl'))) {
            $url = set_url_scheme($url, 'https');
        }
        $args = array('timeout' => 15, 'body' => array('action' => $action, 'request' => serialize($args)));
        $request = wp_remote_post($url, $args);
        if ($ssl && is_wp_error($request)) {
            trigger_error(__('An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="http://wordpress.org/support/">support forums</a>.') . ' ' . '(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);
        }
        if (is_wp_error($request)) {
            $res = new WP_Error('plugins_api_failed', __('An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="http://wordpress.org/support/">support forums</a>.'), $request->get_error_message());
        } else {
            $res = maybe_unserialize(wp_remote_retrieve_body($request));
            if (!is_object($res) && !is_array($res)) {
                $res = new WP_Error('plugins_api_failed', __('An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="http://wordpress.org/support/">support forums</a>.'), wp_remote_retrieve_body($request));
            }
        }
    } elseif (!is_wp_error($res)) {
        $res->external = true;
    }
    /**
     * Filter the Plugin Install API response results.
     *
     * @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);
}

WordPress Version: 3.7

/**
 * WordPress Plugin Install Administration API
 *
 * @package WordPress
 * @subpackage Administration
 */
/**
 * Retrieve plugin installer pages from WordPress 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
 * 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 second filter, 'plugins_api', is the result that would be returned.
 *
 * @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.
 */
function plugins_api($action, $args = null)
{
    if (is_array($args)) {
        $args = (object) $args;
    }
    if (!isset($args->per_page)) {
        $args->per_page = 24;
    }
    /**
     * Override the Plugin Install API arguments.
     *
     * Please ensure that an object is returned.
     *
     * @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);
    /**
     * Allows a plugin to override the WordPress.org Plugin Install API entirely.
     *
     * Please ensure that an object is returned.
     *
     * @since 2.7.0
     *
     * @param bool|object         The result object. Default is 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);
    if (false === $res) {
        $url = 'http://api.wordpress.org/plugins/info/1.0/';
        if (wp_http_supports(array('ssl'))) {
            $url = set_url_scheme($url, 'https');
        }
        $request = wp_remote_post($url, array('timeout' => 15, 'body' => array('action' => $action, 'request' => serialize($args))));
        if (is_wp_error($request)) {
            $res = new WP_Error('plugins_api_failed', __('An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="http://wordpress.org/support/">support forums</a>.'), $request->get_error_message());
        } else {
            $res = maybe_unserialize(wp_remote_retrieve_body($request));
            if (!is_object($res) && !is_array($res)) {
                $res = new WP_Error('plugins_api_failed', __('An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="http://wordpress.org/support/">support forums</a>.'), wp_remote_retrieve_body($request));
            }
        }
    } elseif (!is_wp_error($res)) {
        $res->external = true;
    }
    /**
     * Filter the Plugin Install API response results.
     *
     * @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);
}