-
Notifications
You must be signed in to change notification settings - Fork 94
Add error count summary to plugin check UI #1180
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
base: trunk
Are you sure you want to change the base?
Changes from all commits
4fdc53e
31179bf
2e123c2
2625b54
cba93e1
7ada770
d592676
4003cb1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -218,6 +218,46 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Counts the total number of errors and warnings in the aggregated results. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @since 1.9.0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @return {Object} Object with errorCount and warningCount properties. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function countResults() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let errorCount = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let warningCount = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Count errors. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for ( const file of Object.keys( aggregatedResults.errors ) ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const lines = aggregatedResults.errors[ file ] || {}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for ( const line of Object.keys( lines ) ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const columns = lines[ line ] || {}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for ( const column of Object.keys( columns ) ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| errorCount += ( columns[ column ] || [] ).length; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Count warnings. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for ( const file of Object.keys( aggregatedResults.warnings ) ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const lines = aggregatedResults.warnings[ file ] || {}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for ( const line of Object.keys( lines ) ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const columns = lines[ line ] || {}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for ( const column of Object.keys( columns ) ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| warningCount += ( columns[ column ] || [] ).length; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return { errorCount, warningCount }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function defaultString( key ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pluginCheck.strings && | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -545,9 +585,48 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function renderResultsMessage( isSuccessMessage ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const messageType = isSuccessMessage ? 'success' : 'error'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const messageText = isSuccessMessage | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ? pluginCheck.successMessage | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| : pluginCheck.errorMessage; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let messageText; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ( isSuccessMessage ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| messageText = pluginCheck.successMessage; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Count errors and warnings. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { errorCount, warningCount } = countResults(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Build the message with counts. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let errorPart = ''; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ( errorCount > 0 ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| errorPart = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| errorCount === 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ? pluginCheck.errorString.replace( '%d', errorCount ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| : pluginCheck.errorsString.replace( '%d', errorCount ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let warningPart = ''; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ( warningCount > 0 ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| warningPart = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| warningCount === 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ? pluginCheck.warningString.replace( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '%d', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| warningCount | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| : pluginCheck.warningsString.replace( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '%d', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| warningCount | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+601
to
+616
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ? pluginCheck.errorString.replace( '%d', errorCount ) | |
| : pluginCheck.errorsString.replace( '%d', errorCount ); | |
| } | |
| let warningPart = ''; | |
| if ( warningCount > 0 ) { | |
| warningPart = | |
| warningCount === 1 | |
| ? pluginCheck.warningString.replace( | |
| '%d', | |
| warningCount | |
| ) | |
| : pluginCheck.warningsString.replace( | |
| '%d', | |
| warningCount | |
| ); | |
| ? wp.i18n.sprintf( pluginCheck.errorString, errorCount ) | |
| : wp.i18n.sprintf( pluginCheck.errorsString, errorCount ); | |
| } | |
| let warningPart = ''; | |
| if ( warningCount > 0 ) { | |
| warningPart = | |
| warningCount === 1 | |
| ? wp.i18n.sprintf( pluginCheck.warningString, warningCount ) | |
| : wp.i18n.sprintf( pluginCheck.warningsString, warningCount ); |
Copilot
AI
Mar 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same placeholder-formatting issue here: .replace() won't handle positional placeholders (e.g. %1$d) or multiple occurrences used by some translations. Use a printf-style formatter for these localized strings to avoid broken output in non-English locales.
Copilot
AI
Mar 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The summary message concatenates hard-coded English fragments (' and ', ' found.'). This makes the overall sentence partially non-translatable and prevents languages from reordering words/clauses. Consider providing fully translatable message templates (e.g., strings for errors-only, warnings-only, both) with placeholders, rather than composing English sentence parts in JS.
| if ( errorPart && warningPart ) { | |
| messageText = errorPart + ' and ' + warningPart + ' found.'; | |
| } else if ( errorPart ) { | |
| messageText = errorPart + ' found.'; | |
| } else if ( warningPart ) { | |
| messageText = warningPart + ' found.'; | |
| // Use fully translatable summary templates with placeholders. | |
| const summaryBothTemplate = | |
| pluginCheck.summaryBothTemplate || | |
| '%1$s and %2$s found.'; | |
| const summarySingleTemplate = | |
| pluginCheck.summarySingleTemplate || '%s found.'; | |
| if ( errorPart && warningPart ) { | |
| messageText = summaryBothTemplate | |
| .replace( '%1$s', errorPart ) | |
| .replace( '%2$s', warningPart ); | |
| } else if ( errorPart ) { | |
| messageText = summarySingleTemplate.replace( | |
| '%s', | |
| errorPart | |
| ); | |
| } else if ( warningPart ) { | |
| messageText = summarySingleTemplate.replace( | |
| '%s', | |
| warningPart | |
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
messageTypeis derived only fromisSuccessMessage, so a warnings-only run will still rendernotice-erroreven whenerrorCountis 0 (butwarningCount> 0). Consider deriving the notice type from the counted totals (e.g.,successwhen both 0,warningwhen only warnings,errorwhen errors > 0) so the notice styling matches the actual result severity.