From 2acd3978eb86bd70c48291a7dfd0a04637e55b2b Mon Sep 17 00:00:00 2001
From: frantorres
Date: Sun, 14 Jun 2026 21:32:13 +0200
Subject: [PATCH 1/4] Plugin directory: Prevent duplicated plugin submissions
using guardrails both in the frontend and in the backend.
---
.../plugin-directory/shortcodes/class-upload.php | 15 +++++++++++++--
.../themes/pub/wporg-plugins-2024/functions.php | 6 ++++++
.../themes/pub/wporg-plugins-2024/js/upload.js | 15 +++++++++++++++
3 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/class-upload.php b/wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/class-upload.php
index ea5d8acb0e..b32845c127 100644
--- a/wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/class-upload.php
+++ b/wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/class-upload.php
@@ -97,8 +97,19 @@ public static function display() {
wp_verify_nonce( $_POST['_wpnonce'], 'wporg-plugins-upload-' . $_POST['plugin_id'] )
)
) {
- $for_plugin = absint( $_POST['plugin_id'] ?? 0 );
- $upload_result = $uploader->process_upload( $for_plugin );
+ $for_plugin = absint( $_POST['plugin_id'] ?? 0 );
+
+ // Lock to prevent duplicate submissions from double-clicks or page reloads
+ $lock_key = 'plugin_upload_lock_' . get_current_user_id() . '_' . $for_plugin;
+ if ( false === wp_cache_add( $lock_key, time(), 'wporg-plugins', 5 * MINUTE_IN_SECONDS ) ) {
+ $upload_result = new \WP_Error(
+ 'upload_in_progress',
+ __( 'Your previous upload is still being processed. Please wait a moment before trying again.', 'wporg-plugins' )
+ );
+ } else {
+ $upload_result = $uploader->process_upload( $for_plugin );
+ wp_cache_delete( $lock_key, 'wporg-plugins' );
+ }
if ( is_wp_error( $upload_result ) ) {
$type = 'error';
diff --git a/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/functions.php b/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/functions.php
index e798728a31..6662070d15 100644
--- a/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/functions.php
+++ b/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/functions.php
@@ -137,6 +137,12 @@ function scripts() {
// The plugin submission page: /developers/add/
if ( is_page( 'add' ) ) {
wp_enqueue_script( 'wporg-plugins-upload', get_stylesheet_directory_uri() . '/js/upload.js', array( 'wp-api', 'jquery' ), filemtime( __DIR__ . '/js/upload.js' ), true );
+
+ wp_localize_script( 'wporg-plugins-upload', 'pluginUpload', array(
+ 'l10n' => array(
+ 'uploading' => __( 'Uploading…', 'wporg-plugins' ),
+ ),
+ ) );
}
// No Jetpack scripts needed.
diff --git a/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/js/upload.js b/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/js/upload.js
index 3212ec6a3f..cbd3028c3c 100644
--- a/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/js/upload.js
+++ b/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/js/upload.js
@@ -49,4 +49,19 @@
$(this).hide().parents('ul').find('.plugin-upload-form.hidden').removeClass( 'hidden' );
} );
+ // Prevent duplicate submissions by disabling the submit button
+ $( 'form.plugin-upload-form' ).on( 'submit', function() {
+ var $button = $(this).find( 'input[type="submit"]' );
+
+ $button.prop( 'disabled', true );
+
+ if ( ! $button.data( 'defaultValue' ) ) {
+ $button.data( 'defaultValue', $button.val() );
+ }
+
+ if ( 'undefined' !== typeof pluginUpload && pluginUpload.l10n && pluginUpload.l10n.uploading ) {
+ $button.val( pluginUpload.l10n.uploading );
+ }
+ } );
+
})( jQuery );
From d96440b7f3ce8f8aa8ecb05a82c14a46bcf21f73 Mon Sep 17 00:00:00 2001
From: frantorres
Date: Sun, 14 Jun 2026 21:45:16 +0200
Subject: [PATCH 2/4] Linting
---
.../themes/pub/wporg-plugins-2024/functions.php | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/functions.php b/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/functions.php
index 6662070d15..b988f44eef 100644
--- a/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/functions.php
+++ b/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/functions.php
@@ -138,11 +138,15 @@ function scripts() {
if ( is_page( 'add' ) ) {
wp_enqueue_script( 'wporg-plugins-upload', get_stylesheet_directory_uri() . '/js/upload.js', array( 'wp-api', 'jquery' ), filemtime( __DIR__ . '/js/upload.js' ), true );
- wp_localize_script( 'wporg-plugins-upload', 'pluginUpload', array(
- 'l10n' => array(
- 'uploading' => __( 'Uploading…', 'wporg-plugins' ),
- ),
- ) );
+ wp_localize_script(
+ 'wporg-plugins-upload',
+ 'pluginUpload',
+ array(
+ 'l10n' => array(
+ 'uploading' => __( 'Uploading…', 'wporg-plugins' ),
+ ),
+ )
+ );
}
// No Jetpack scripts needed.
From d86d40d45b695c404658dcb6af8793c9fe654a65 Mon Sep 17 00:00:00 2001
From: frantorres
Date: Wed, 15 Jul 2026 18:49:10 +0200
Subject: [PATCH 3/4] Upload button, passing the uploading string as a data
attribute.
---
.../plugin-directory/shortcodes/class-upload.php | 4 ++--
.../themes/pub/wporg-plugins-2024/functions.php | 10 ----------
.../themes/pub/wporg-plugins-2024/js/upload.js | 11 ++++-------
3 files changed, 6 insertions(+), 19 deletions(-)
diff --git a/wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/class-upload.php b/wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/class-upload.php
index b32845c127..3b17a178f9 100644
--- a/wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/class-upload.php
+++ b/wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/class-upload.php
@@ -379,7 +379,7 @@ public static function display() {
-
+
';
@@ -580,7 +580,7 @@ public static function display() {
-
+
array(
- 'uploading' => __( 'Uploading…', 'wporg-plugins' ),
- ),
- )
- );
}
// No Jetpack scripts needed.
diff --git a/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/js/upload.js b/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/js/upload.js
index cbd3028c3c..7e4cc57a1c 100644
--- a/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/js/upload.js
+++ b/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/js/upload.js
@@ -51,16 +51,13 @@
// Prevent duplicate submissions by disabling the submit button
$( 'form.plugin-upload-form' ).on( 'submit', function() {
- var $button = $(this).find( 'input[type="submit"]' );
+ var $button = $(this).find( 'input[type="submit"]' ),
+ uploadingLabel = $button.data( 'uploadingLabel' );
$button.prop( 'disabled', true );
- if ( ! $button.data( 'defaultValue' ) ) {
- $button.data( 'defaultValue', $button.val() );
- }
-
- if ( 'undefined' !== typeof pluginUpload && pluginUpload.l10n && pluginUpload.l10n.uploading ) {
- $button.val( pluginUpload.l10n.uploading );
+ if ( uploadingLabel ) {
+ $button.val( uploadingLabel );
}
} );
From 893c3c24ccf72d1d8d3cb8d0b8df31b60eec7058 Mon Sep 17 00:00:00 2001
From: frantorres
Date: Wed, 15 Jul 2026 18:51:24 +0200
Subject: [PATCH 4/4] Lint
---
.../plugins/plugin-directory/shortcodes/class-upload.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/class-upload.php b/wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/class-upload.php
index 3b17a178f9..c545fea943 100644
--- a/wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/class-upload.php
+++ b/wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/class-upload.php
@@ -379,7 +379,7 @@ public static function display() {
-
+
';