'', 'features' => '', // toggles (default true) 'short_description' => 'true', 'requires' => 'true', 'requires_php' => 'true', 'version' => 'true', 'downloaded' => 'true', 'active_installs' => 'true', 'last_updated' => 'true', 'rating' => 'true', 'num_ratings' => 'true', 'homepage' => 'true', 'icons' => 'true', 'contributors' => 'true', ], $atts, 'wporg_plugin_widget' ); $url = trim( $atts['url'] ); if ( empty( $url ) ) { return '
'; } // Derive slug from the URL. $parts = wp_parse_url( $url ); if ( empty( $parts['path'] ) ) { return ''; } $segments = array_values( array_filter( explode( '/', $parts['path'] ), static function ( $seg ) { return '' !== $seg; } ) ); $slug = end( $segments ); $slug = sanitize_title( $slug ); if ( empty( $slug ) ) { return ''; } // Ensure plugins_api() is available. if ( ! function_exists( 'plugins_api' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; } $convert_to_bool = function ( $value, $default_value ) { if ( is_bool( $value ) ) { return $value; } if ( is_null( $value ) ) { return $default_value; } return filter_var( $value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE ) ?? $default_value; }; // Boolean toggles. $show_short_desc = $convert_to_bool( $atts['short_description'], true ); $show_requires = $convert_to_bool( $atts['requires'], true ); $show_requiresphp = $convert_to_bool( $atts['requires_php'], true ); $show_version = $convert_to_bool( $atts['version'], true ); $show_downloaded = $convert_to_bool( $atts['downloaded'], true ); $show_installs = $convert_to_bool( $atts['active_installs'], true ); $show_updated = $convert_to_bool( $atts['last_updated'], true ); $show_rating = $convert_to_bool( $atts['rating'], true ); $show_numratings = $convert_to_bool( $atts['num_ratings'], true ); $show_homepage = $convert_to_bool( $atts['homepage'], true ); $show_icons = $convert_to_bool( $atts['icons'], true ); $show_contrib = $convert_to_bool( $atts['contributors'], true ); $atts_hash = md5( wp_json_encode( $atts ) ); $transient_key = 'wporg_pw_' . $slug . '_' . $atts_hash; $plugin = get_transient( $transient_key ); if ( false === $plugin ) { $args = [ 'slug' => $slug, 'fields' => [ 'short_description' => $show_short_desc, 'sections' => true, 'requires' => $show_requires, 'requires_php' => $show_requiresphp, 'tested' => true, 'version' => $show_version, 'downloaded' => $show_downloaded, 'active_installs' => $show_installs, 'last_updated' => $show_updated, 'rating' => $show_rating, 'num_ratings' => $show_numratings, 'homepage' => $show_homepage, 'icons' => $show_icons, 'contributors' => $show_contrib, ], ]; $plugin = plugins_api( 'plugin_information', $args ); if ( ! is_wp_error( $plugin ) ) { // Cache for 12 hours. set_transient( $transient_key, $plugin, 12 * HOUR_IN_SECONDS ); } } if ( is_wp_error( $plugin ) || ! $plugin ) { return ''; } // Parse features attribute. $features = []; if ( ! empty( $atts['features'] ) ) { $raw_features = explode( '|', $atts['features'] ); foreach ( $raw_features as $feature ) { $feature = trim( sanitize_text_field( $feature ) ); if ( '' !== $feature ) { $features[] = $feature; } } } ob_start(); // Determine description HTML: // - show BOTH short_description and long "description" section as one flowing unit // - only show "Show more" button if there is a long description. $description_html = ''; $has_long_desc = false; $short_html = ''; $long_html = ''; if ( ! empty( $plugin->short_description ) ) { // short_description is plain text, so escape and wrap in. $short_html = '
' . esc_html( $plugin->short_description ) . '
'; } if ( ! empty( $plugin->sections ) && ! empty( $plugin->sections['description'] ) ) { // sections['description'] is HTML: sanitize but keep formatting. $long_html = wp_kses_post( $plugin->sections['description'] ); $has_long_desc = true; } if ( $short_html || $long_html ) { $description_html = $short_html . $long_html; } $icon_url = ''; if ( $show_icons && ! empty( $plugin->icons ) && is_array( $plugin->icons ) ) { if ( ! empty( $plugin->icons['2x'] ) ) { $icon_url = $plugin->icons['2x']; } elseif ( ! empty( $plugin->icons['1x'] ) ) { $icon_url = $plugin->icons['1x']; } elseif ( ! empty( $plugin->icons['default'] ) ) { $icon_url = $plugin->icons['default']; } } $rating_raw = isset( $plugin->rating ) ? floatval( $plugin->rating ) : 0; // 0–100. $num_ratings = isset( $plugin->num_ratings ) ? intval( $plugin->num_ratings ) : 0; $active_installs = isset( $plugin->active_installs ) ? intval( $plugin->active_installs ) : 0; ?>