Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid passing incomplete data to perflab_render_plugin_card() and show error when plugin directory API query fails #1175

Merged
Merged
4 changes: 2 additions & 2 deletions includes/admin/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -260,14 +260,14 @@ function perflab_install_activate_plugin_callback() {
$api = perflab_query_plugin_info( $plugin_slug );

// Return early if plugin API returns an error.
if ( ! $api ) {
if ( $api instanceof WP_Error ) {
wp_die(
wp_kses(
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>.', 'default' ),
__( 'https://wordpress.org/support/forums/', 'default' )
),
) . ' ' . $api->get_error_message(),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now the specific error is shown rather than just the generic message.

array( 'a' => array( 'href' => true ) )
)
);
Expand Down
71 changes: 43 additions & 28 deletions includes/admin/plugins.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* @since 2.8.0
*
* @param string $plugin_slug The string identifier for the plugin in questions slug.
* @return array Array of plugin data, or empty if none/error.
* @return array{name: string, slug: string, short_description: string, requires: string|false, requires_php: string|false, requires_plugins: string[], download_link: string}|WP_Error Array of plugin data or WP_Error if failed.
*/
function perflab_query_plugin_info( string $plugin_slug ) {
$plugin = get_transient( 'perflab_plugin_info_' . $plugin_slug );
Expand All @@ -29,14 +29,19 @@ function perflab_query_plugin_info( string $plugin_slug ) {
array(
'slug' => $plugin_slug,
'fields' => array(
'name' => true,
'slug' => true,
'short_description' => true,
'icons' => true,
'requires' => true,
'requires_php' => true,
'requires_plugins' => true,
'download_link' => true,
),
)
);

if ( is_wp_error( $plugin ) ) {
return array();
return $plugin;
}

if ( is_object( $plugin ) ) {
Expand Down Expand Up @@ -74,20 +79,41 @@ function perflab_render_plugins_ui() {
$experimental_plugins = array();

foreach ( perflab_get_standalone_plugin_data() as $plugin_slug => $plugin_data ) {
$api_data = perflab_query_plugin_info( $plugin_slug ); // Data from wordpress.org.

// Skip if the plugin is not on WordPress.org or there was a network error.
if ( $api_data instanceof WP_Error ) {
wp_admin_notice(
esc_html(
sprintf(
/* translators: %s is the plugin slug */
__( 'Failed to query WordPress.org Plugin Directory for plugin "%s".', 'performance-lab' ) . ' %s',
$plugin_slug,
$api_data->get_error_message()
westonruter marked this conversation as resolved.
Show resolved Hide resolved
)
),
array( 'type' => 'error' )
);
continue;
}

$plugin_data = array_merge(
array(
'experimental' => false,
),
$plugin_data, // Data defined within Performance Lab.
perflab_query_plugin_info( $plugin_slug ) // Data from wordpress.org.
$api_data
);

// Separate experimental plugins so that they're displayed after non-experimental plugins.
if ( isset( $plugin_data['experimental'] ) && $plugin_data['experimental'] ) {
if ( $plugin_data['experimental'] ) {
$experimental_plugins[ $plugin_slug ] = $plugin_data;
} else {
$plugins[ $plugin_slug ] = $plugin_data;
}
}

if ( empty( $plugins ) ) {
if ( ! $plugins && ! $experimental_plugins ) {
return;
}
?>
Expand Down Expand Up @@ -125,22 +151,15 @@ function perflab_render_plugins_ui() {
* @see WP_Plugin_Install_List_Table::display_rows()
* @link https://github.com/WordPress/wordpress-develop/blob/0b8ca16ea3bd9722bd1a38f8ab68901506b1a0e7/src/wp-admin/includes/class-wp-plugin-install-list-table.php#L467-L830
*
* @param array $plugin_data Plugin data from the WordPress.org API.
* @param array{name: string, slug: string, short_description: string, requires_php: string|false, requires: string|false, requires_plugins: string[], experimental: bool} $plugin_data Plugin data augmenting data from the WordPress.org API.
*/
function perflab_render_plugin_card( array $plugin_data ) {
// If no plugin data is returned, return.
if ( empty( $plugin_data ) ) {
return;
}

// Remove any HTML from the description.
$name = wp_strip_all_tags( $plugin_data['name'] );
$description = wp_strip_all_tags( $plugin_data['short_description'] );
$title = $plugin_data['name'];

/** This filter is documented in wp-admin/includes/class-wp-plugin-install-list-table.php */
$description = apply_filters( 'plugin_install_description', $description, $plugin_data );
$version = $plugin_data['version'];
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't see a need for the version to be mentioned among the features, so I removed it.

$name = wp_strip_all_tags( $title . ' ' . $version );

$requires_php = isset( $plugin_data['requires_php'] ) ? $plugin_data['requires_php'] : null;
$requires_wp = isset( $plugin_data['requires'] ) ? $plugin_data['requires'] : null;
Expand Down Expand Up @@ -193,7 +212,7 @@ function perflab_render_plugin_card( array $plugin_data ) {
);
}

if ( isset( $plugin_data['slug'] ) && current_user_can( 'install_plugins' ) ) {
if ( current_user_can( 'install_plugins' ) ) {
$title_link_attr = ' class="thickbox open-plugin-details-modal"';
$details_link = esc_url_raw(
add_query_arg(
Expand Down Expand Up @@ -297,25 +316,21 @@ function perflab_render_plugin_card( array $plugin_data ) {
<div class="name column-name">
<h3>
<a href="<?php echo esc_url( $details_link ); ?>"<?php echo $title_link_attr; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
<?php echo wp_kses_post( $title ); ?>
<?php echo wp_kses_post( $name ); ?>
</a>
<?php
if ( isset( $plugin_data['experimental'] ) && $plugin_data['experimental'] ) {
?>
<?php if ( $plugin_data['experimental'] ) : ?>
<em class="perflab-plugin-experimental">
<?php echo esc_html( _x( '(experimental)', 'plugin suffix', 'performance-lab' ) ); ?>
</em>
<?php
}
?>
<?php endif; ?>
</h3>
</div>
<div class="action-links">
<?php
if ( ! empty( $action_links ) ) {
echo wp_kses_post( '<ul class="plugin-action-buttons"><li>' . implode( '</li><li>', $action_links ) . '</li></ul>' );
}
?>
<ul class="plugin-action-buttons">
<?php foreach ( $action_links as $action_link ) : ?>
<li><?php echo wp_kses_post( $action_link ); ?></li>
<?php endforeach; ?>
</ul>
</div>
<div class="desc column-description">
<p><?php echo wp_kses_post( $description ); ?></p>
Expand Down
Loading