From c3d781e6c9433777df8df67d2c79d0c9d482f3de Mon Sep 17 00:00:00 2001 From: Dion Hulse Date: Thu, 14 May 2026 16:19:03 +1000 Subject: [PATCH 1/3] Plugin Directory: Hide the ElasticSearch metabox when it cannot be useful. Skip rendering for draft/pending plugins (nothing is indexed yet) and on local environments without Jetpack Search available (the AJAX call would just report that Jetpack Search is unavailable). Co-Authored-By: Claude Opus 4.7 (1M context) --- .../admin/class-customizations.php | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/class-customizations.php b/wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/class-customizations.php index d1e30f3c4b..f45ebae34e 100644 --- a/wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/class-customizations.php +++ b/wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/class-customizations.php @@ -787,12 +787,20 @@ public function register_admin_metaboxes( $post_type, $post ) { ); } - add_meta_box( - 'plugin-elasticsearch', - __( 'ElasticSearch Index', 'wporg-plugins' ), - array( __NAMESPACE__ . '\Metabox\Elasticsearch', 'display' ), - 'plugin', 'normal', 'low' - ); + // The ElasticSearch metabox is only useful for published plugins, and on + // environments where Jetpack Search can actually query the index. + $es_environment = in_array( wp_get_environment_type(), array( 'production', 'staging' ), true ); + $es_available = class_exists( '\Automattic\Jetpack\Search\Classic_Search' ); + $es_draft = in_array( $post->post_status, array( 'draft', 'pending' ), true ); + + if ( ! $es_draft && ( $es_environment || $es_available ) ) { + add_meta_box( + 'plugin-elasticsearch', + __( 'ElasticSearch Index', 'wporg-plugins' ), + array( __NAMESPACE__ . '\Metabox\Elasticsearch', 'display' ), + 'plugin', 'normal', 'low' + ); + } // Remove unnecessary metaboxes. remove_meta_box( 'commentsdiv', 'plugin', 'normal' ); From c036f457b45b9d53e06799e316f4ffb270396498 Mon Sep 17 00:00:00 2001 From: Dion Hulse Date: Thu, 14 May 2026 16:19:10 +1000 Subject: [PATCH 2/3] Plugin Directory: Local env mu-plugin to populate post_author for CLI inserts. The production import-plugin.php --create path calls create_plugin_post() with only post_name, so wp_insert_post() defaults post_author to get_current_user_id(), which is 0 in CLI. This leaves the plugin post with no resolvable author, which in turn produces a string of PHP warnings in the wp-admin Review Tools metabox. Add a local mu-plugin that hooks wp_insert_post_data: when a new plugin post is being inserted in CLI without a post_author, fetch the embedded author from the wp.org REST API and create the matching local user. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../mu-plugins/wporg-plugin-author-import.php | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 environments/mocks/mu-plugins/wporg-plugin-author-import.php diff --git a/environments/mocks/mu-plugins/wporg-plugin-author-import.php b/environments/mocks/mu-plugins/wporg-plugin-author-import.php new file mode 100644 index 0000000000..21c50f3a64 --- /dev/null +++ b/environments/mocks/mu-plugins/wporg-plugin-author-import.php @@ -0,0 +1,117 @@ + $slug, + '_embed' => 1, + 'per_page' => 1, + ), + 'https://wordpress.org/plugins/wp-json/wp/v2/plugin' + ); + + $response = wp_remote_get( $url, array( 'timeout' => 30 ) ); + if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) { + return null; + } + + $results = json_decode( wp_remote_retrieve_body( $response ), true ); + if ( empty( $results[0]['_embedded']['author'][0]['slug'] ) ) { + return null; + } + + return $results[0]['_embedded']['author'][0]; +} + +/** + * Find or create a local user matching the given wp.org author payload. + * + * @param array $author Author array from the REST API (must include slug). + * @return int User ID, or 0 on failure. + */ +function ensure_local_user( array $author ) { + $slug = $author['slug']; + + $existing = get_user_by( 'slug', $slug ); + if ( $existing ) { + return (int) $existing->ID; + } + + $user_id = wp_insert_user( array( + 'user_login' => $slug, + 'user_nicename' => $slug, + 'user_email' => $slug . '@example.invalid', + 'display_name' => $author['name'] ?? $slug, + 'user_url' => $author['url'] ?? '', + 'user_pass' => wp_generate_password(), + 'role' => 'subscriber', + ) ); + + if ( is_wp_error( $user_id ) ) { + fwrite( STDERR, "[wporg-plugin-author-import] wp_insert_user failed for {$slug}: " . $user_id->get_error_message() . "\n" ); + return 0; + } + + return (int) $user_id; +} From 149e2e4cf401b260116fd0979a40d23a530d4d31 Mon Sep 17 00:00:00 2001 From: Dion Hulse Date: Thu, 14 May 2026 16:38:13 +1000 Subject: [PATCH 3/3] Plugin Directory: Simplify the ElasticSearch metabox visibility check. Move it into the existing post-approval block (alongside committers, support reps, etc.) so it only renders for plugins that have moved past new/pending, and keep the class_exists guard so it stays hidden when Jetpack Search is not loaded locally. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../admin/class-customizations.php | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/class-customizations.php b/wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/class-customizations.php index f45ebae34e..9adf692411 100644 --- a/wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/class-customizations.php +++ b/wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/class-customizations.php @@ -785,21 +785,15 @@ public function register_admin_metaboxes( $post_type, $post ) { array( __NAMESPACE__ . '\Metabox\Author_Notice', 'display' ), 'plugin', 'normal', 'high' ); - } - - // The ElasticSearch metabox is only useful for published plugins, and on - // environments where Jetpack Search can actually query the index. - $es_environment = in_array( wp_get_environment_type(), array( 'production', 'staging' ), true ); - $es_available = class_exists( '\Automattic\Jetpack\Search\Classic_Search' ); - $es_draft = in_array( $post->post_status, array( 'draft', 'pending' ), true ); - if ( ! $es_draft && ( $es_environment || $es_available ) ) { - add_meta_box( - 'plugin-elasticsearch', - __( 'ElasticSearch Index', 'wporg-plugins' ), - array( __NAMESPACE__ . '\Metabox\Elasticsearch', 'display' ), - 'plugin', 'normal', 'low' - ); + if ( class_exists( '\Automattic\Jetpack\Search\Classic_Search' ) ) { + add_meta_box( + 'plugin-elasticsearch', + __( 'ElasticSearch Index', 'wporg-plugins' ), + array( __NAMESPACE__ . '\Metabox\Elasticsearch', 'display' ), + 'plugin', 'normal', 'low' + ); + } } // Remove unnecessary metaboxes.