Commit 8881dc3f7dd for woocommerce
commit 8881dc3f7ddbeb133c249b805807e208965f2b26
Author: Vlad Olaru <vlad.olaru@automattic.com>
Date: Fri Oct 23 23:07:37 2026 +0300
Keep developer diagnostic messages in English on every site language (#69754)
* fix(i18n): keep developer diagnostic messages in English
WooCommerce translated the messages it passes to developer
diagnostics: wc_doing_it_wrong(), _doing_it_wrong(), trigger_error(),
error_log() and the replacement text of deprecation notices. On a
multilingual store the same notice appeared in a different language
on each request, so log filters and support searches for the English
text missed it.
Pass English strings instead. esc_html__() becomes esc_html() on the
literal, so English output keeps its entity encoding byte for byte,
and the one _n() call becomes an explicit singular/plural choice.
This also covers values that only feed a diagnostic: the Settings UI
conversion notices and cached failure reasons, and two
FeaturesController notices sent through LegacyProxy. Shopper and
merchant text, including the Packages admin notice, stays translated.
WordPress still translates its own wrapper around these messages.
Tests intercept gettext and ngettext so the payloads are checked
under a translating locale.
Refs #53790
* chore(phpcs): flag translated developer diagnostic messages
Six translated diagnostics landed in four PRs between June and
September 2026, so a one-off cleanup erodes without a rule.
Add WooCommerceInternal.I18n.DiagnosticMessage next to the existing
local sniffs. It reports a WordPress translation call inside the
message of wc_doing_it_wrong(), _doing_it_wrong(), trigger_error(),
wp_trigger_error(), user_error(), error_log() and the deprecation
notices, including calls made through LegacyProxy::call_function().
It reads parameters by position or name and ignores method calls
that share a function's name.
It cannot follow a translated string passed in through a variable,
property or wrapper; the README says so. The fixture documents the
flagged and allowed cases.
Refs #53790
* chore(changelog): document English developer diagnostics
Record the merchant-facing note that WooCommerce developer notices
and debug log messages are now English on every site language.
Refs #53790
* docs(phpcs): fix the PHPCS path in the %i sniff example
The README's example for the IdentifierPlaceholder sniff ran
bin/composer/phpcs/vendor/bin/phpcs, which is never created. The
bamarni/composer-bin-plugin keeps bin-links on by default and
composer.json only overrides target-directory, so the plugin links
each namespace's executables into the root vendor/bin instead.
Use vendor/bin/phpcs, matching the DiagnosticMessage example below it
and the dev-cycle skill docs.
Refs #53790
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(i18n): keep extensible abilities and MCP diagnostics in English
Trunk merges brought in ExtensibleAbilities (#69684, #69960) and
McpEndpointRemoval (#69787) after this branch converted the existing
developer diagnostics. Their wc_doing_it_wrong() messages still went
through __(), so a misused extension API logged a translated notice
on non-English sites, and the new DiagnosticMessage sniff reported 23
errors across the two files.
Pass the English strings directly and drop the translators comments.
Schema descriptions, REST and JSON-RPC error responses, and the admin
notice stay translated, since people and API clients read them.
Refs #53790
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
diff --git a/plugins/woocommerce/changelog/fix-stable-developer-diagnostics b/plugins/woocommerce/changelog/fix-stable-developer-diagnostics
new file mode 100644
index 00000000000..6bd8fa6ba36
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-stable-developer-diagnostics
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Show WooCommerce developer notices and debug log messages in English on every site language, so they are easy to search.
diff --git a/plugins/woocommerce/includes/abstracts/abstract-wc-data.php b/plugins/woocommerce/includes/abstracts/abstract-wc-data.php
index bf8101cd03d..1118eb167bc 100644
--- a/plugins/woocommerce/includes/abstracts/abstract-wc-data.php
+++ b/plugins/woocommerce/includes/abstracts/abstract-wc-data.php
@@ -397,8 +397,7 @@ abstract class WC_Data {
return true; // return without warning because we don't want to break legacy code which was calling add/get/update/delete meta.
}
- /* translators: %s: $key Key to check */
- wc_doing_it_wrong( __FUNCTION__, sprintf( __( 'Generic add/update/get meta methods should not be used for internal meta data, including "%s". Use getters and setters.', 'woocommerce' ), $key ), '3.2.0' );
+ wc_doing_it_wrong( __FUNCTION__, sprintf( 'Generic add/update/get meta methods should not be used for internal meta data, including "%s". Use getters and setters.', $key ), '3.2.0' );
return true;
}
diff --git a/plugins/woocommerce/includes/abstracts/abstract-wc-order.php b/plugins/woocommerce/includes/abstracts/abstract-wc-order.php
index b3186a92058..9de8b284543 100644
--- a/plugins/woocommerce/includes/abstracts/abstract-wc-order.php
+++ b/plugins/woocommerce/includes/abstracts/abstract-wc-order.php
@@ -1141,8 +1141,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
if ( null !== $type && ! is_string( $type ) ) {
wc_doing_it_wrong(
__METHOD__,
- /* translators: %s: PHP type that was passed instead of a string. */
- sprintf( esc_html__( 'remove_order_items() expects a string item type or null; received %s.', 'woocommerce' ), esc_html( gettype( $type ) ) ),
+ sprintf( esc_html( 'remove_order_items() expects a string item type or null; received %s.' ), esc_html( gettype( $type ) ) ),
'11.0.0'
);
return;
diff --git a/plugins/woocommerce/includes/admin/class-wc-admin-notices.php b/plugins/woocommerce/includes/admin/class-wc-admin-notices.php
index 406bc6e14a8..6d5dbd18286 100644
--- a/plugins/woocommerce/includes/admin/class-wc-admin-notices.php
+++ b/plugins/woocommerce/includes/admin/class-wc-admin-notices.php
@@ -485,7 +485,7 @@ class WC_Admin_Notices {
* @return void
*/
public static function install_notice() {
- _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', esc_html__( 'Onboarding is maintained in WooCommerce Admin.', 'woocommerce' ) );
+ _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', esc_html( 'Onboarding is maintained in WooCommerce Admin.' ) );
}
/**
diff --git a/plugins/woocommerce/includes/admin/settings/class-wc-settings-page.php b/plugins/woocommerce/includes/admin/settings/class-wc-settings-page.php
index 27d371995fc..37ede6a7d8a 100644
--- a/plugins/woocommerce/includes/admin/settings/class-wc-settings-page.php
+++ b/plugins/woocommerce/includes/admin/settings/class-wc-settings-page.php
@@ -190,8 +190,7 @@ if ( ! class_exists( 'WC_Settings_Page', false ) ) :
wc_doing_it_wrong(
'WC_Settings_Page::output',
sprintf(
- /* translators: 1: settings page id, 2: settings section id, 3: fallback reason. */
- __( 'Settings UI rendering for page "%1$s" section "%2$s" fell back to the legacy settings renderer. Reason: %3$s', 'woocommerce' ),
+ 'Settings UI rendering for page "%1$s" section "%2$s" fell back to the legacy settings renderer. Reason: %3$s',
$page_id,
'' === $section_id ? 'default' : $section_id,
$reason
@@ -426,7 +425,7 @@ if ( ! class_exists( 'WC_Settings_Page', false ) ) :
if ( $context->has_schema_failed() ) {
$schema_failure_reason = method_exists( $context, 'get_schema_failure_reason' )
? $context->get_schema_failure_reason()
- : __( 'Settings UI schema generation failed.', 'woocommerce' );
+ : 'Settings UI schema generation failed.';
$this->log_settings_ui_fallback( $page_id, $section, $schema_failure_reason );
} else {
diff --git a/plugins/woocommerce/includes/class-wc-cart.php b/plugins/woocommerce/includes/class-wc-cart.php
index 76f7327a2d1..e846548bbc9 100644
--- a/plugins/woocommerce/includes/class-wc-cart.php
+++ b/plugins/woocommerce/includes/class-wc-cart.php
@@ -666,7 +666,7 @@ class WC_Cart extends WC_Legacy_Cart {
*/
public function get_cart() {
if ( ! did_action( 'wp_loaded' ) ) {
- wc_doing_it_wrong( __FUNCTION__, __( 'Get cart should not be called before the wp_loaded action.', 'woocommerce' ), '2.3' );
+ wc_doing_it_wrong( __FUNCTION__, 'Get cart should not be called before the wp_loaded action.', '2.3' );
}
if ( ! did_action( 'woocommerce_load_cart_from_session' ) ) {
$this->session->get_cart_from_session();
@@ -2058,7 +2058,7 @@ class WC_Cart extends WC_Legacy_Cart {
public function is_coupon_emails_allowed( $check_emails, $restrictions ) {
wc_doing_it_wrong(
'WC_Cart::is_coupon_emails_allowed',
- __( 'This method has been deprecated and will be removed soon. Use Automattic\WooCommerce\Utilities\DiscountsUtil::is_coupon_emails_allowed instead.', 'woocommerce' ),
+ 'This method has been deprecated and will be removed soon. Use Automattic\WooCommerce\Utilities\DiscountsUtil::is_coupon_emails_allowed instead.',
'9.0.0'
);
diff --git a/plugins/woocommerce/includes/class-wc-checkout.php b/plugins/woocommerce/includes/class-wc-checkout.php
index 095c26c01a4..31ecf30eb1a 100644
--- a/plugins/woocommerce/includes/class-wc-checkout.php
+++ b/plugins/woocommerce/includes/class-wc-checkout.php
@@ -194,14 +194,14 @@ class WC_Checkout {
* Cloning is forbidden.
*/
public function __clone() {
- wc_doing_it_wrong( __FUNCTION__, __( 'Cloning is forbidden.', 'woocommerce' ), '2.1' );
+ wc_doing_it_wrong( __FUNCTION__, 'Cloning is forbidden.', '2.1' );
}
/**
* Unserializing instances of this class is forbidden.
*/
public function __wakeup() {
- wc_doing_it_wrong( __FUNCTION__, __( 'Unserializing instances of this class is forbidden.', 'woocommerce' ), '2.1' );
+ wc_doing_it_wrong( __FUNCTION__, 'Unserializing instances of this class is forbidden.', '2.1' );
}
/**
diff --git a/plugins/woocommerce/includes/class-wc-emails.php b/plugins/woocommerce/includes/class-wc-emails.php
index c855da5dc0e..5ec9f6a74c5 100644
--- a/plugins/woocommerce/includes/class-wc-emails.php
+++ b/plugins/woocommerce/includes/class-wc-emails.php
@@ -70,7 +70,7 @@ class WC_Emails {
* @return void
*/
public function __clone() {
- wc_doing_it_wrong( __FUNCTION__, __( 'Cloning is forbidden.', 'woocommerce' ), '2.1' );
+ wc_doing_it_wrong( __FUNCTION__, 'Cloning is forbidden.', '2.1' );
}
/**
@@ -80,7 +80,7 @@ class WC_Emails {
* @return void
*/
public function __wakeup() {
- wc_doing_it_wrong( __FUNCTION__, __( 'Unserializing instances of this class is forbidden.', 'woocommerce' ), '2.1' );
+ wc_doing_it_wrong( __FUNCTION__, 'Unserializing instances of this class is forbidden.', '2.1' );
}
/**
diff --git a/plugins/woocommerce/includes/class-wc-logger.php b/plugins/woocommerce/includes/class-wc-logger.php
index 9b24140c3b7..87ce22a8182 100644
--- a/plugins/woocommerce/includes/class-wc-logger.php
+++ b/plugins/woocommerce/includes/class-wc-logger.php
@@ -77,8 +77,7 @@ class WC_Logger implements WC_Logger_Interface {
wc_doing_it_wrong(
__METHOD__,
sprintf(
- /* translators: 1: class name 2: WC_Log_Handler_Interface */
- __( 'The provided handler %1$s does not implement %2$s.', 'woocommerce' ),
+ 'The provided handler %1$s does not implement %2$s.',
'<code>' . esc_html( is_object( $handler ) ? get_class( $handler ) : $handler ) . '</code>',
'<code>WC_Log_Handler_Interface</code>'
),
@@ -166,8 +165,7 @@ class WC_Logger implements WC_Logger_Interface {
*/
public function log( $level, $message, $context = array() ) {
if ( ! WC_Log_Levels::is_valid_level( $level ) ) {
- /* translators: 1: WC_Logger::log 2: level */
- wc_doing_it_wrong( __METHOD__, sprintf( __( '%1$s was called with an invalid level "%2$s".', 'woocommerce' ), '<code>WC_Logger::log</code>', $level ), '3.0' );
+ wc_doing_it_wrong( __METHOD__, sprintf( '%1$s was called with an invalid level "%2$s".', '<code>WC_Logger::log</code>', $level ), '3.0' );
}
if ( $this->should_handle( $level ) ) {
diff --git a/plugins/woocommerce/includes/class-wc-payment-gateways.php b/plugins/woocommerce/includes/class-wc-payment-gateways.php
index 0a16f9d1771..2385abf06db 100644
--- a/plugins/woocommerce/includes/class-wc-payment-gateways.php
+++ b/plugins/woocommerce/includes/class-wc-payment-gateways.php
@@ -58,7 +58,7 @@ class WC_Payment_Gateways {
* @since 2.1
*/
public function __clone() {
- wc_doing_it_wrong( __FUNCTION__, __( 'Cloning is forbidden.', 'woocommerce' ), '2.1' );
+ wc_doing_it_wrong( __FUNCTION__, 'Cloning is forbidden.', '2.1' );
}
/**
@@ -67,7 +67,7 @@ class WC_Payment_Gateways {
* @since 2.1
*/
public function __wakeup() {
- wc_doing_it_wrong( __FUNCTION__, __( 'Unserializing instances of this class is forbidden.', 'woocommerce' ), '2.1' );
+ wc_doing_it_wrong( __FUNCTION__, 'Unserializing instances of this class is forbidden.', '2.1' );
}
/**
diff --git a/plugins/woocommerce/includes/class-wc-shipping.php b/plugins/woocommerce/includes/class-wc-shipping.php
index 1c9e335f90e..38659a62754 100644
--- a/plugins/woocommerce/includes/class-wc-shipping.php
+++ b/plugins/woocommerce/includes/class-wc-shipping.php
@@ -77,7 +77,7 @@ class WC_Shipping {
* @since 2.1
*/
public function __clone() {
- wc_doing_it_wrong( __FUNCTION__, __( 'Cloning is forbidden.', 'woocommerce' ), '2.1' );
+ wc_doing_it_wrong( __FUNCTION__, 'Cloning is forbidden.', '2.1' );
}
/**
@@ -86,7 +86,7 @@ class WC_Shipping {
* @since 2.1
*/
public function __wakeup() {
- wc_doing_it_wrong( __FUNCTION__, __( 'Unserializing instances of this class is forbidden.', 'woocommerce' ), '2.1' );
+ wc_doing_it_wrong( __FUNCTION__, 'Unserializing instances of this class is forbidden.', '2.1' );
}
/**
diff --git a/plugins/woocommerce/includes/class-woocommerce.php b/plugins/woocommerce/includes/class-woocommerce.php
index 5b55b555e6c..62ce80550a6 100644
--- a/plugins/woocommerce/includes/class-woocommerce.php
+++ b/plugins/woocommerce/includes/class-woocommerce.php
@@ -196,7 +196,7 @@ final class WooCommerce {
* @return void
*/
public function __clone() {
- wc_doing_it_wrong( __FUNCTION__, __( 'Cloning is forbidden.', 'woocommerce' ), '2.1' );
+ wc_doing_it_wrong( __FUNCTION__, 'Cloning is forbidden.', '2.1' );
}
/**
@@ -207,7 +207,7 @@ final class WooCommerce {
* @return void
*/
public function __wakeup() {
- wc_doing_it_wrong( __FUNCTION__, __( 'Unserializing instances of this class is forbidden.', 'woocommerce' ), '2.1' );
+ wc_doing_it_wrong( __FUNCTION__, 'Unserializing instances of this class is forbidden.', '2.1' );
}
/**
diff --git a/plugins/woocommerce/includes/data-stores/class-wc-customer-data-store-session.php b/plugins/woocommerce/includes/data-stores/class-wc-customer-data-store-session.php
index fde569c1c62..507d6983c62 100644
--- a/plugins/woocommerce/includes/data-stores/class-wc-customer-data-store-session.php
+++ b/plugins/woocommerce/includes/data-stores/class-wc-customer-data-store-session.php
@@ -91,7 +91,7 @@ class WC_Customer_Data_Store_Session extends WC_Data_Store_WP implements WC_Cust
if ( ! WC()->session ) {
wc_doing_it_wrong(
__METHOD__,
- __( 'WC_Session is not available, customer data cannot be saved to session.', 'woocommerce' ),
+ 'WC_Session is not available, customer data cannot be saved to session.',
'9.8.0'
);
return;
diff --git a/plugins/woocommerce/includes/data-stores/class-wc-customer-download-data-store.php b/plugins/woocommerce/includes/data-stores/class-wc-customer-download-data-store.php
index 6ea463a86bd..e6f2a219ea1 100644
--- a/plugins/woocommerce/includes/data-stores/class-wc-customer-download-data-store.php
+++ b/plugins/woocommerce/includes/data-stores/class-wc-customer-download-data-store.php
@@ -289,7 +289,7 @@ class WC_Customer_Download_Data_Store implements WC_Customer_Download_Data_Store
} elseif ( is_float( $value ) ) {
$value_placeholder = '%f';
} else {
- wc_doing_it_wrong( __METHOD__, __( 'Unsupported argument type provided as value.', 'woocommerce' ), '7.0' );
+ wc_doing_it_wrong( __METHOD__, 'Unsupported argument type provided as value.', '7.0' );
// The `prepare` further down would fail if the placeholder was missing, so skip download log removal.
return;
}
diff --git a/plugins/woocommerce/includes/data-stores/class-wc-order-data-store-cpt.php b/plugins/woocommerce/includes/data-stores/class-wc-order-data-store-cpt.php
index a8b976dc7a8..f90c364d1ad 100644
--- a/plugins/woocommerce/includes/data-stores/class-wc-order-data-store-cpt.php
+++ b/plugins/woocommerce/includes/data-stores/class-wc-order-data-store-cpt.php
@@ -1085,13 +1085,9 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
__METHOD__,
esc_html(
sprintf(
- // translators: %s is a comma separated list of query arguments.
- _n(
- 'Order query argument (%s) is not supported on the current order datastore.',
- 'Order query arguments (%s) are not supported on the current order datastore.',
- count( $unsupported_args_in_query ),
- 'woocommerce'
- ),
+ 1 === count( $unsupported_args_in_query )
+ ? 'Order query argument (%s) is not supported on the current order datastore.'
+ : 'Order query arguments (%s) are not supported on the current order datastore.',
implode( ', ', $unsupported_args_in_query )
)
),
diff --git a/plugins/woocommerce/includes/data-stores/class-wc-product-variable-data-store-cpt.php b/plugins/woocommerce/includes/data-stores/class-wc-product-variable-data-store-cpt.php
index cc5f9c957da..dac5845469c 100644
--- a/plugins/woocommerce/includes/data-stores/class-wc-product-variable-data-store-cpt.php
+++ b/plugins/woocommerce/includes/data-stores/class-wc-product-variable-data-store-cpt.php
@@ -578,7 +578,7 @@ class WC_Product_Variable_Data_Store_CPT extends WC_Product_Data_Store_CPT imple
if ( $this->prices_array[ $hash_display ] !== $transient_cached_prices_array[ $hash_display ] && ! $this->validate_prices_data( array( $hash_display => $this->prices_array[ $hash_display ] ), $transient_version ) ) {
wc_doing_it_wrong(
__METHOD__,
- __( '`woocommerce_variation_prices` returned an unsupported data format. The value is currently used as-is but will be ignored in a future release. Ensure your callback returns the expected array structure.', 'woocommerce' ),
+ '`woocommerce_variation_prices` returned an unsupported data format. The value is currently used as-is but will be ignored in a future release. Ensure your callback returns the expected array structure.',
'11.1'
);
}
@@ -587,7 +587,7 @@ class WC_Product_Variable_Data_Store_CPT extends WC_Product_Data_Store_CPT imple
if ( $this->prices_array[ $hash_raw ] !== $transient_cached_prices_array[ $hash_raw ] && ! $this->validate_prices_data( array( $hash_raw => $this->prices_array[ $hash_raw ] ), $transient_version ) ) {
wc_doing_it_wrong(
__METHOD__,
- __( '`woocommerce_variation_prices` returned an unsupported data format. The value is currently used as-is but will be ignored in a future release. Ensure your callback returns the expected array structure.', 'woocommerce' ),
+ '`woocommerce_variation_prices` returned an unsupported data format. The value is currently used as-is but will be ignored in a future release. Ensure your callback returns the expected array structure.',
'11.1'
);
}
diff --git a/plugins/woocommerce/includes/legacy/abstract-wc-legacy-product.php b/plugins/woocommerce/includes/legacy/abstract-wc-legacy-product.php
index 72d363e12b1..4783b3d5698 100644
--- a/plugins/woocommerce/includes/legacy/abstract-wc-legacy-product.php
+++ b/plugins/woocommerce/includes/legacy/abstract-wc-legacy-product.php
@@ -72,7 +72,7 @@ abstract class WC_Abstract_Legacy_Product extends WC_Data {
return $this->post_type;
}
- wc_doing_it_wrong( $key, __( 'Product properties should not be accessed directly.', 'woocommerce' ), '3.0' );
+ wc_doing_it_wrong( $key, 'Product properties should not be accessed directly.', '3.0' );
switch ( $key ) {
case 'id' :
diff --git a/plugins/woocommerce/includes/log-handlers/class-wc-log-handler-file.php b/plugins/woocommerce/includes/log-handlers/class-wc-log-handler-file.php
index 2e8f413bf53..6d2967da793 100644
--- a/plugins/woocommerce/includes/log-handlers/class-wc-log-handler-file.php
+++ b/plugins/woocommerce/includes/log-handlers/class-wc-log-handler-file.php
@@ -356,7 +356,7 @@ class WC_Log_Handler_File extends WC_Log_Handler {
if ( function_exists( 'wp_hash' ) ) {
return trailingslashit( $log_directory ) . self::get_log_file_name( $handle );
} else {
- wc_doing_it_wrong( __METHOD__, __( 'This method should not be called before plugins_loaded.', 'woocommerce' ), '3.0' );
+ wc_doing_it_wrong( __METHOD__, 'This method should not be called before plugins_loaded.', '3.0' );
return false;
}
}
@@ -376,7 +376,7 @@ class WC_Log_Handler_File extends WC_Log_Handler {
$hash_suffix = wp_hash( $handle );
return sanitize_file_name( implode( '-', array( $handle, $date_suffix, $hash_suffix ) ) . '.log' );
} else {
- wc_doing_it_wrong( __METHOD__, __( 'This method should not be called before plugins_loaded.', 'woocommerce' ), '3.3' );
+ wc_doing_it_wrong( __METHOD__, 'This method should not be called before plugins_loaded.', '3.3' );
return false;
}
}
diff --git a/plugins/woocommerce/includes/queue/class-wc-queue.php b/plugins/woocommerce/includes/queue/class-wc-queue.php
index 80dd4b67a95..949f91f34bc 100644
--- a/plugins/woocommerce/includes/queue/class-wc-queue.php
+++ b/plugins/woocommerce/includes/queue/class-wc-queue.php
@@ -57,7 +57,7 @@ class WC_Queue {
*/
protected static function get_class() {
if ( ! did_action( 'plugins_loaded' ) ) {
- wc_doing_it_wrong( __FUNCTION__, __( 'This function should not be called before plugins_loaded.', 'woocommerce' ), '3.5.0' );
+ wc_doing_it_wrong( __FUNCTION__, 'This function should not be called before plugins_loaded.', '3.5.0' );
}
return apply_filters( 'woocommerce_queue_class', self::$default_cass );
@@ -72,8 +72,7 @@ class WC_Queue {
protected static function validate_instance( $instance ) {
if ( false === ( $instance instanceof WC_Queue_Interface ) ) {
$default_class = self::$default_cass;
- /* translators: %s: Default class name */
- wc_doing_it_wrong( __FUNCTION__, sprintf( __( 'The class attached to the "woocommerce_queue_class" does not implement the WC_Queue_Interface interface. The default %s class will be used instead.', 'woocommerce' ), $default_class ), '3.5.0' );
+ wc_doing_it_wrong( __FUNCTION__, sprintf( 'The class attached to the "woocommerce_queue_class" does not implement the WC_Queue_Interface interface. The default %s class will be used instead.', $default_class ), '3.5.0' );
$instance = new $default_class();
}
diff --git a/plugins/woocommerce/includes/rest-api/Utilities/SingletonTrait.php b/plugins/woocommerce/includes/rest-api/Utilities/SingletonTrait.php
index b713a6ccbd2..8a23687b513 100644
--- a/plugins/woocommerce/includes/rest-api/Utilities/SingletonTrait.php
+++ b/plugins/woocommerce/includes/rest-api/Utilities/SingletonTrait.php
@@ -46,7 +46,7 @@ trait SingletonTrait {
* Prevent unserializing.
*/
final public function __wakeup() {
- wc_doing_it_wrong( __FUNCTION__, __( 'Unserializing instances of this class is forbidden.', 'woocommerce' ), '4.6' );
+ wc_doing_it_wrong( __FUNCTION__, 'Unserializing instances of this class is forbidden.', '4.6' );
die();
}
}
diff --git a/plugins/woocommerce/includes/tracks/events/class-wc-admin-setup-wizard-tracking.php b/plugins/woocommerce/includes/tracks/events/class-wc-admin-setup-wizard-tracking.php
index 158904c8f9d..58d7e3ab2cf 100644
--- a/plugins/woocommerce/includes/tracks/events/class-wc-admin-setup-wizard-tracking.php
+++ b/plugins/woocommerce/includes/tracks/events/class-wc-admin-setup-wizard-tracking.php
@@ -26,7 +26,7 @@ class WC_Admin_Setup_Wizard_Tracking {
* @deprecated 4.6.0
*/
public function init() {
- _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', __( 'Onboarding is maintained in WooCommerce Admin.', 'woocommerce' ) );
+ _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' );
}
/**
@@ -36,7 +36,7 @@ class WC_Admin_Setup_Wizard_Tracking {
* @return string
*/
public function get_current_step() {
- _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', __( 'Onboarding is maintained in WooCommerce Admin.', 'woocommerce' ) );
+ _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' );
return isset( $_GET['step'] ) ? sanitize_key( $_GET['step'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
}
@@ -46,7 +46,7 @@ class WC_Admin_Setup_Wizard_Tracking {
* @deprecated 4.6.0
*/
public function add_footer_scripts() {
- _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', __( 'Onboarding is maintained in WooCommerce Admin.', 'woocommerce' ) );
+ _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' );
}
/**
@@ -55,7 +55,7 @@ class WC_Admin_Setup_Wizard_Tracking {
* @deprecated 4.6.0
*/
public function dequeue_non_allowed_scripts() {
- _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', __( 'Onboarding is maintained in WooCommerce Admin.', 'woocommerce' ) );
+ _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' );
global $wp_scripts;
$allowed = array( 'woo-tracks' );
@@ -76,7 +76,7 @@ class WC_Admin_Setup_Wizard_Tracking {
* @deprecated 4.6.0
*/
public function track_start( $option, $value ) {
- _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', __( 'Onboarding is maintained in WooCommerce Admin.', 'woocommerce' ) );
+ _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' );
}
/**
@@ -85,7 +85,7 @@ class WC_Admin_Setup_Wizard_Tracking {
* @deprecated 4.6.0
*/
public function track_ready_next_steps() {
- _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', __( 'Onboarding is maintained in WooCommerce Admin.', 'woocommerce' ) );
+ _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' );
}
/**
@@ -94,7 +94,7 @@ class WC_Admin_Setup_Wizard_Tracking {
* @deprecated 4.6.0
*/
public function add_step_save_events() {
- _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', __( 'Onboarding is maintained in WooCommerce Admin.', 'woocommerce' ) );
+ _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' );
}
/**
@@ -103,7 +103,7 @@ class WC_Admin_Setup_Wizard_Tracking {
* @deprecated 4.6.0
*/
public function track_store_setup() {
- _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', __( 'Onboarding is maintained in WooCommerce Admin.', 'woocommerce' ) );
+ _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' );
}
/**
@@ -112,7 +112,7 @@ class WC_Admin_Setup_Wizard_Tracking {
* @deprecated 4.6.0
*/
public function track_payments() {
- _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', __( 'Onboarding is maintained in WooCommerce Admin.', 'woocommerce' ) );
+ _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' );
}
/**
@@ -121,7 +121,7 @@ class WC_Admin_Setup_Wizard_Tracking {
* @deprecated 4.6.0
*/
public function track_shipping() {
- _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', __( 'Onboarding is maintained in WooCommerce Admin.', 'woocommerce' ) );
+ _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' );
}
/**
@@ -130,7 +130,7 @@ class WC_Admin_Setup_Wizard_Tracking {
* @deprecated 4.6.0
*/
public function track_recommended() {
- _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', __( 'Onboarding is maintained in WooCommerce Admin.', 'woocommerce' ) );
+ _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' );
}
/**
@@ -139,7 +139,7 @@ class WC_Admin_Setup_Wizard_Tracking {
* @deprecated 4.6.0
*/
public function track_jetpack_activate() {
- _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', __( 'Onboarding is maintained in WooCommerce Admin.', 'woocommerce' ) );
+ _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' );
}
/**
@@ -148,7 +148,7 @@ class WC_Admin_Setup_Wizard_Tracking {
* @deprecated 4.6.0
*/
public function track_next_steps() {
- _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', __( 'Onboarding is maintained in WooCommerce Admin.', 'woocommerce' ) );
+ _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' );
}
/**
@@ -157,7 +157,7 @@ class WC_Admin_Setup_Wizard_Tracking {
* @deprecated 4.6.0
*/
public function track_skip_step() {
- _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', __( 'Onboarding is maintained in WooCommerce Admin.', 'woocommerce' ) );
+ _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' );
}
/**
@@ -168,7 +168,7 @@ class WC_Admin_Setup_Wizard_Tracking {
* @deprecated 4.6.0
*/
public function set_obw_steps( $steps ) {
- _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', __( 'Onboarding is maintained in WooCommerce Admin.', 'woocommerce' ) );
+ _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' );
$this->steps = $steps;
return $steps;
diff --git a/plugins/woocommerce/includes/wc-core-functions.php b/plugins/woocommerce/includes/wc-core-functions.php
index 05fab8992cb..c0c83d873df 100644
--- a/plugins/woocommerce/includes/wc-core-functions.php
+++ b/plugins/woocommerce/includes/wc-core-functions.php
@@ -319,8 +319,7 @@ function wc_get_template( $template_name, $args = array(), $template_path = '',
if ( $filter_template !== $template ) {
if ( ! file_exists( $filter_template ) ) {
- /* translators: %s template */
- wc_doing_it_wrong( __FUNCTION__, sprintf( __( '%s does not exist.', 'woocommerce' ), '<code>' . $filter_template . '</code>' ), '2.1' );
+ wc_doing_it_wrong( __FUNCTION__, sprintf( '%s does not exist.', '<code>' . $filter_template . '</code>' ), '2.1' );
return;
}
$template = $filter_template;
@@ -337,7 +336,7 @@ function wc_get_template( $template_name, $args = array(), $template_path = '',
if ( isset( $args['action_args'] ) ) {
wc_doing_it_wrong(
__FUNCTION__,
- __( 'action_args should not be overwritten when calling wc_get_template.', 'woocommerce' ),
+ 'action_args should not be overwritten when calling wc_get_template.',
'3.6.0'
);
unset( $args['action_args'] );
@@ -2014,8 +2013,7 @@ function wc_get_logger() {
wc_doing_it_wrong(
__FUNCTION__,
sprintf(
- /* translators: 1: class name 2: woocommerce_logging_class 3: WC_Logger_Interface */
- __( 'The class %1$s provided by %2$s filter must implement %3$s.', 'woocommerce' ),
+ 'The class %1$s provided by %2$s filter must implement %3$s.',
'<code>' . esc_html( is_object( $class ) ? get_class( $class ) : $class ) . '</code>',
'<code>woocommerce_logging_class</code>',
'<code>WC_Logger_Interface</code>'
@@ -2536,8 +2534,7 @@ function wc_get_server_database_version() {
*/
function wc_load_cart() {
if ( ! did_action( 'before_woocommerce_init' ) || doing_action( 'before_woocommerce_init' ) ) {
- /* translators: 1: wc_load_cart 2: woocommerce_init */
- wc_doing_it_wrong( __FUNCTION__, sprintf( __( '%1$s should not be called before the %2$s action.', 'woocommerce' ), 'wc_load_cart', 'woocommerce_init' ), '3.7' );
+ wc_doing_it_wrong( __FUNCTION__, sprintf( '%1$s should not be called before the %2$s action.', 'wc_load_cart', 'woocommerce_init' ), '3.7' );
return;
}
diff --git a/plugins/woocommerce/includes/wc-notice-functions.php b/plugins/woocommerce/includes/wc-notice-functions.php
index b1a715a8d5b..c4145f6d6b1 100644
--- a/plugins/woocommerce/includes/wc-notice-functions.php
+++ b/plugins/woocommerce/includes/wc-notice-functions.php
@@ -22,7 +22,7 @@ if ( ! defined( 'ABSPATH' ) ) {
*/
function wc_notice_count( $notice_type = '' ) {
if ( ! did_action( 'woocommerce_init' ) ) {
- wc_doing_it_wrong( __FUNCTION__, __( 'This function should not be called before woocommerce_init.', 'woocommerce' ), '2.3' );
+ wc_doing_it_wrong( __FUNCTION__, 'This function should not be called before woocommerce_init.', '2.3' );
return;
}
@@ -55,7 +55,7 @@ function wc_notice_count( $notice_type = '' ) {
*/
function wc_has_notice( $message, $notice_type = 'success' ) {
if ( ! did_action( 'woocommerce_init' ) ) {
- wc_doing_it_wrong( __FUNCTION__, __( 'This function should not be called before woocommerce_init.', 'woocommerce' ), '2.3' );
+ wc_doing_it_wrong( __FUNCTION__, 'This function should not be called before woocommerce_init.', '2.3' );
return false;
}
@@ -75,14 +75,14 @@ function wc_has_notice( $message, $notice_type = 'success' ) {
*/
function wc_add_notice( $message, $notice_type = 'success', $data = array() ) {
if ( ! did_action( 'woocommerce_init' ) ) {
- wc_doing_it_wrong( __FUNCTION__, __( 'This function should not be called before woocommerce_init.', 'woocommerce' ), '2.3' );
+ wc_doing_it_wrong( __FUNCTION__, 'This function should not be called before woocommerce_init.', '2.3' );
return;
}
// If this is called before the session is initialized, for example if a plugin includes this file incorrectly on
// the admin, skip doing anything to prevent errors.
if ( ! WC()->session ) {
- wc_doing_it_wrong( __FUNCTION__, __( 'This function should not be called before the WooCommerce session is initialized, or places where there is no session, e.g. WordPress admin.', 'woocommerce' ), '10.5' );
+ wc_doing_it_wrong( __FUNCTION__, 'This function should not be called before the WooCommerce session is initialized, or places where there is no session, e.g. WordPress admin.', '10.5' );
return;
}
@@ -113,7 +113,7 @@ function wc_add_notice( $message, $notice_type = 'success', $data = array() ) {
*/
function wc_set_notices( $notices ) {
if ( ! did_action( 'woocommerce_init' ) ) {
- wc_doing_it_wrong( __FUNCTION__, __( 'This function should not be called before woocommerce_init.', 'woocommerce' ), '2.6' );
+ wc_doing_it_wrong( __FUNCTION__, 'This function should not be called before woocommerce_init.', '2.6' );
return;
}
@@ -127,7 +127,7 @@ function wc_set_notices( $notices ) {
*/
function wc_clear_notices() {
if ( ! did_action( 'woocommerce_init' ) ) {
- wc_doing_it_wrong( __FUNCTION__, __( 'This function should not be called before woocommerce_init.', 'woocommerce' ), '2.3' );
+ wc_doing_it_wrong( __FUNCTION__, 'This function should not be called before woocommerce_init.', '2.3' );
return;
}
WC()->session->set( 'wc_notices', null );
@@ -142,7 +142,7 @@ function wc_clear_notices() {
*/
function wc_print_notices( $return = false ) {
if ( ! did_action( 'woocommerce_init' ) ) {
- wc_doing_it_wrong( __FUNCTION__, __( 'This function should not be called before woocommerce_init.', 'woocommerce' ), '2.3' );
+ wc_doing_it_wrong( __FUNCTION__, 'This function should not be called before woocommerce_init.', '2.3' );
return;
}
@@ -240,7 +240,7 @@ function wc_print_notice( $message, $notice_type = 'success', $data = array(), $
*/
function wc_get_notices( $notice_type = '' ) {
if ( ! did_action( 'woocommerce_init' ) ) {
- wc_doing_it_wrong( __FUNCTION__, __( 'This function should not be called before woocommerce_init.', 'woocommerce' ), '2.3' );
+ wc_doing_it_wrong( __FUNCTION__, 'This function should not be called before woocommerce_init.', '2.3' );
return;
}
diff --git a/plugins/woocommerce/includes/wc-order-functions.php b/plugins/woocommerce/includes/wc-order-functions.php
index 111ddb10d75..84192d84177 100644
--- a/plugins/woocommerce/includes/wc-order-functions.php
+++ b/plugins/woocommerce/includes/wc-order-functions.php
@@ -183,7 +183,7 @@ function wc_get_order_status_name( $status ) {
if ( ! is_string( $status ) ) {
wc_doing_it_wrong(
__FUNCTION__,
- __( 'An invalid order status slug was supplied.', 'woocommerce' ),
+ 'An invalid order status slug was supplied.',
'9.6'
);
}
diff --git a/plugins/woocommerce/includes/wc-product-functions.php b/plugins/woocommerce/includes/wc-product-functions.php
index 4dac815d335..2a75cd65db9 100644
--- a/plugins/woocommerce/includes/wc-product-functions.php
+++ b/plugins/woocommerce/includes/wc-product-functions.php
@@ -71,8 +71,7 @@ function wc_get_products( $args ) {
*/
function wc_get_product( $the_product = false, $deprecated = array() ) {
if ( ! did_action( 'woocommerce_init' ) || ! did_action( 'woocommerce_after_register_taxonomy' ) || ! did_action( 'woocommerce_after_register_post_type' ) ) {
- /* translators: 1: wc_get_product 2: woocommerce_init 3: woocommerce_after_register_taxonomy 4: woocommerce_after_register_post_type */
- wc_doing_it_wrong( __FUNCTION__, sprintf( __( '%1$s should not be called before the %2$s, %3$s and %4$s actions have finished.', 'woocommerce' ), 'wc_get_product', 'woocommerce_init', 'woocommerce_after_register_taxonomy', 'woocommerce_after_register_post_type' ), '3.9' );
+ wc_doing_it_wrong( __FUNCTION__, sprintf( '%1$s should not be called before the %2$s, %3$s and %4$s actions have finished.', 'wc_get_product', 'woocommerce_init', 'woocommerce_after_register_taxonomy', 'woocommerce_after_register_post_type' ), '3.9' );
return false;
}
if ( ! empty( $deprecated ) ) {
@@ -1761,8 +1760,7 @@ function wc_get_product_category_list( $product_id, $sep = ', ', $before = '', $
wc_doing_it_wrong(
__FUNCTION__,
sprintf(
- /* translators: 1: the unsupported ordering mode that was passed. */
- __( 'Unsupported $orderby value "%1$s". Use "name", "breadcrumb", or an empty string for WordPress term-list order.', 'woocommerce' ),
+ 'Unsupported $orderby value "%1$s". Use "name", "breadcrumb", or an empty string for WordPress term-list order.',
is_scalar( $orderby ) ? (string) $orderby : gettype( $orderby )
),
'11.2.0'
diff --git a/plugins/woocommerce/includes/wc-template-functions.php b/plugins/woocommerce/includes/wc-template-functions.php
index 6efe81fff82..26ba5c94168 100644
--- a/plugins/woocommerce/includes/wc-template-functions.php
+++ b/plugins/woocommerce/includes/wc-template-functions.php
@@ -2944,7 +2944,7 @@ if ( ! function_exists( 'woocommerce_checkout_payment' ) ) {
if ( ! WC()->cart ) {
wc_doing_it_wrong(
__FUNCTION__,
- __( 'Cart is not available. This may indicate that the function is being called before woocommerce_init or in an admin context.', 'woocommerce' ),
+ 'Cart is not available. This may indicate that the function is being called before woocommerce_init or in an admin context.',
'9.8.0'
);
return;
diff --git a/plugins/woocommerce/phpcs.xml b/plugins/woocommerce/phpcs.xml
index 4bddbc1c73c..6398838d27e 100644
--- a/plugins/woocommerce/phpcs.xml
+++ b/plugins/woocommerce/phpcs.xml
@@ -53,6 +53,12 @@
<include-pattern>includes/</include-pattern>
</rule>
+ <!-- Local sniff: developer diagnostic messages (wc_doing_it_wrong(), trigger_error(), error_log(), deprecation notices) stay in English. -->
+ <rule ref="./tests/Tools/phpcs/WooCommerceInternal/Sniffs/I18n/DiagnosticMessageSniff.php">
+ <include-pattern>src/</include-pattern>
+ <include-pattern>includes/</include-pattern>
+ </rule>
+
<!-- The cart token selects which customer session loads; it must be read from one place only. -->
<rule ref="./bin/phpcs/WooCommerceStoreApi/Sniffs/StoreApi/CartTokenSourceSniff.php">
<!-- The canonical accessor, and tests that simulate raw request headers. -->
diff --git a/plugins/woocommerce/src/Abilities/ExtensibleAbilities.php b/plugins/woocommerce/src/Abilities/ExtensibleAbilities.php
index f89a3e5a6f1..15b5f8a4162 100644
--- a/plugins/woocommerce/src/Abilities/ExtensibleAbilities.php
+++ b/plugins/woocommerce/src/Abilities/ExtensibleAbilities.php
@@ -99,11 +99,11 @@ class ExtensibleAbilities {
*/
public static function register_resource( string $resource_name ): void {
if ( did_action( 'woocommerce_extensible_abilities_resources_init' ) && ! doing_action( 'woocommerce_extensible_abilities_resources_init' ) ) {
- wc_doing_it_wrong( __METHOD__, __( 'Register a resource inside the woocommerce_extensible_abilities_resources_init action, before the fields are registered.', 'woocommerce' ), '11.3.0' );
+ wc_doing_it_wrong( __METHOD__, 'Register a resource inside the woocommerce_extensible_abilities_resources_init action, before the fields are registered.', '11.3.0' );
return;
}
if ( '' === $resource_name || sanitize_key( $resource_name ) !== $resource_name || ctype_digit( $resource_name ) ) {
- wc_doing_it_wrong( __METHOD__, __( 'The resource name must be a slug of lowercase letters, numbers, dashes and underscores, not only numbers.', 'woocommerce' ), '11.3.0' );
+ wc_doing_it_wrong( __METHOD__, 'The resource name must be a slug of lowercase letters, numbers, dashes and underscores, not only numbers.', '11.3.0' );
return;
}
@@ -143,7 +143,7 @@ class ExtensibleAbilities {
*/
public static function register_field( array $args ): void {
if ( did_action( 'woocommerce_extensible_abilities_init' ) && ! doing_action( 'woocommerce_extensible_abilities_init' ) ) {
- wc_doing_it_wrong( __METHOD__, __( 'Register a field inside the woocommerce_extensible_abilities_init action, before the abilities build their schemas.', 'woocommerce' ), '11.3.0' );
+ wc_doing_it_wrong( __METHOD__, 'Register a field inside the woocommerce_extensible_abilities_init action, before the abilities build their schemas.', '11.3.0' );
return;
}
foreach ( array( 'resource', 'namespace', 'field' ) as $key ) {
@@ -151,8 +151,7 @@ class ExtensibleAbilities {
wc_doing_it_wrong(
__METHOD__,
sprintf(
- /* translators: %s: argument name. */
- __( 'The "%s" argument must be a slug of lowercase letters, numbers, dashes and underscores, not only numbers.', 'woocommerce' ),
+ 'The "%s" argument must be a slug of lowercase letters, numbers, dashes and underscores, not only numbers.',
$key
),
'11.3.0'
@@ -161,15 +160,14 @@ class ExtensibleAbilities {
}
}
if ( ! isset( self::$resources[ $args['resource'] ] ) && ! did_action( 'woocommerce_extensible_abilities_resources_init' ) ) {
- wc_doing_it_wrong( __METHOD__, __( 'Register a field inside the woocommerce_extensible_abilities_init action. The resources are not registered yet.', 'woocommerce' ), '11.3.0' );
+ wc_doing_it_wrong( __METHOD__, 'Register a field inside the woocommerce_extensible_abilities_init action. The resources are not registered yet.', '11.3.0' );
return;
}
if ( ! isset( self::$resources[ $args['resource'] ] ) ) {
wc_doing_it_wrong(
__METHOD__,
sprintf(
- /* translators: %s: resource name. */
- __( 'The "%s" resource is not registered. Call ExtensibleAbilities::register_resource() first.', 'woocommerce' ),
+ 'The "%s" resource is not registered. Call ExtensibleAbilities::register_resource() first.',
$args['resource']
),
'11.3.0'
@@ -177,27 +175,26 @@ class ExtensibleAbilities {
return;
}
if ( ! is_array( $args['schema'] ?? null ) || ! isset( $args['schema']['type'] ) ) {
- wc_doing_it_wrong( __METHOD__, __( 'The "schema" argument must be an array with a "type".', 'woocommerce' ), '11.3.0' );
+ wc_doing_it_wrong( __METHOD__, 'The "schema" argument must be an array with a "type".', '11.3.0' );
return;
}
if ( true === ( $args['schema']['required'] ?? null ) ) {
- wc_doing_it_wrong( __METHOD__, __( 'The "schema" argument cannot set "required". A value that fails its schema is left out, so allow null for a field that is always present.', 'woocommerce' ), '11.3.0' );
+ wc_doing_it_wrong( __METHOD__, 'The "schema" argument cannot set "required". A value that fails its schema is left out, so allow null for a field that is always present.', '11.3.0' );
return;
}
if ( ! is_callable( $args['get_callback'] ?? null ) ) {
- wc_doing_it_wrong( __METHOD__, __( 'The "get_callback" argument must be callable.', 'woocommerce' ), '11.3.0' );
+ wc_doing_it_wrong( __METHOD__, 'The "get_callback" argument must be callable.', '11.3.0' );
return;
}
if ( isset( $args['update_callback'] ) && ! is_callable( $args['update_callback'] ) ) {
- wc_doing_it_wrong( __METHOD__, __( 'The "update_callback" argument must be callable.', 'woocommerce' ), '11.3.0' );
+ wc_doing_it_wrong( __METHOD__, 'The "update_callback" argument must be callable.', '11.3.0' );
return;
}
if ( isset( self::$fields[ $args['resource'] ][ $args['namespace'] ][ $args['field'] ] ) ) {
wc_doing_it_wrong(
__METHOD__,
sprintf(
- /* translators: 1: extension namespace, 2: field name, 3: resource name. */
- __( 'The field "%1$s.%2$s" of "%3$s" is already registered.', 'woocommerce' ),
+ 'The field "%1$s.%2$s" of "%3$s" is already registered.',
$args['namespace'],
$args['field'],
$args['resource']
@@ -241,7 +238,7 @@ class ExtensibleAbilities {
*/
public static function register_query_filter( array $args ): void {
if ( did_action( 'woocommerce_extensible_abilities_init' ) && ! doing_action( 'woocommerce_extensible_abilities_init' ) ) {
- wc_doing_it_wrong( __METHOD__, __( 'Register a filter inside the woocommerce_extensible_abilities_init action, before the abilities build their schemas.', 'woocommerce' ), '11.3.0' );
+ wc_doing_it_wrong( __METHOD__, 'Register a filter inside the woocommerce_extensible_abilities_init action, before the abilities build their schemas.', '11.3.0' );
return;
}
foreach ( array( 'resource', 'namespace', 'filter' ) as $key ) {
@@ -249,8 +246,7 @@ class ExtensibleAbilities {
wc_doing_it_wrong(
__METHOD__,
sprintf(
- /* translators: %s: argument name. */
- __( 'The "%s" argument must be a slug of lowercase letters, numbers, dashes and underscores, not only numbers.', 'woocommerce' ),
+ 'The "%s" argument must be a slug of lowercase letters, numbers, dashes and underscores, not only numbers.',
$key
),
'11.3.0'
@@ -262,8 +258,7 @@ class ExtensibleAbilities {
wc_doing_it_wrong(
__METHOD__,
sprintf(
- /* translators: %s: resource name. */
- __( 'The "%s" resource is not registered. Call ExtensibleAbilities::register_resource() first.', 'woocommerce' ),
+ 'The "%s" resource is not registered. Call ExtensibleAbilities::register_resource() first.',
$args['resource']
),
'11.3.0'
@@ -271,19 +266,18 @@ class ExtensibleAbilities {
return;
}
if ( ! is_array( $args['schema'] ?? null ) || ! isset( $args['schema']['type'] ) ) {
- wc_doing_it_wrong( __METHOD__, __( 'The "schema" argument must be an array with a "type".', 'woocommerce' ), '11.3.0' );
+ wc_doing_it_wrong( __METHOD__, 'The "schema" argument must be an array with a "type".', '11.3.0' );
return;
}
if ( ! is_callable( $args['callback'] ?? null ) ) {
- wc_doing_it_wrong( __METHOD__, __( 'The "callback" argument must be callable.', 'woocommerce' ), '11.3.0' );
+ wc_doing_it_wrong( __METHOD__, 'The "callback" argument must be callable.', '11.3.0' );
return;
}
if ( isset( self::$filters[ $args['resource'] ][ $args['namespace'] ][ $args['filter'] ] ) ) {
wc_doing_it_wrong(
__METHOD__,
sprintf(
- /* translators: 1: extension namespace, 2: filter name, 3: resource name. */
- __( 'The filter "%1$s.%2$s" of "%3$s" is already registered.', 'woocommerce' ),
+ 'The filter "%1$s.%2$s" of "%3$s" is already registered.',
$args['namespace'],
$args['filter'],
$args['resource']
@@ -492,7 +486,7 @@ class ExtensibleAbilities {
*/
public static function register_validator( array $args ): void {
if ( did_action( 'woocommerce_extensible_abilities_init' ) && ! doing_action( 'woocommerce_extensible_abilities_init' ) ) {
- wc_doing_it_wrong( __METHOD__, __( 'Register a validator inside the woocommerce_extensible_abilities_init action.', 'woocommerce' ), '11.3.0' );
+ wc_doing_it_wrong( __METHOD__, 'Register a validator inside the woocommerce_extensible_abilities_init action.', '11.3.0' );
return;
}
foreach ( array( 'resource', 'namespace' ) as $key ) {
@@ -500,8 +494,7 @@ class ExtensibleAbilities {
wc_doing_it_wrong(
__METHOD__,
sprintf(
- /* translators: %s: argument name. */
- __( 'The "%s" argument must be a slug of lowercase letters, numbers, dashes and underscores.', 'woocommerce' ),
+ 'The "%s" argument must be a slug of lowercase letters, numbers, dashes and underscores.',
$key
),
'11.3.0'
@@ -510,15 +503,14 @@ class ExtensibleAbilities {
}
}
if ( ! is_callable( $args['callback'] ?? null ) ) {
- wc_doing_it_wrong( __METHOD__, __( 'The "callback" argument must be callable.', 'woocommerce' ), '11.3.0' );
+ wc_doing_it_wrong( __METHOD__, 'The "callback" argument must be callable.', '11.3.0' );
return;
}
if ( ! isset( self::$resources[ $args['resource'] ] ) ) {
wc_doing_it_wrong(
__METHOD__,
sprintf(
- /* translators: %s: resource name. */
- __( 'The "%s" resource is not registered. Call ExtensibleAbilities::register_resource() first.', 'woocommerce' ),
+ 'The "%s" resource is not registered. Call ExtensibleAbilities::register_resource() first.',
$args['resource']
),
'11.3.0'
@@ -667,8 +659,7 @@ class ExtensibleAbilities {
wc_doing_it_wrong(
__CLASS__ . '::register_field',
sprintf(
- /* translators: 1: extension namespace, 2: field name, 3: resource name, 4: validation error. */
- __( 'Ability field "%1$s.%2$s" of "%3$s" was left out because its value does not match its schema: %4$s', 'woocommerce' ),
+ 'Ability field "%1$s.%2$s" of "%3$s" was left out because its value does not match its schema: %4$s',
$args['namespace'],
$args['field'],
$args['resource'],
diff --git a/plugins/woocommerce/src/Admin/PageController.php b/plugins/woocommerce/src/Admin/PageController.php
index 47db11fbe09..1d76fa734d4 100644
--- a/plugins/woocommerce/src/Admin/PageController.php
+++ b/plugins/woocommerce/src/Admin/PageController.php
@@ -232,7 +232,7 @@ class PageController {
// If 'current_screen' hasn't fired yet, the current page calculation
// will fail which causes `false` to be returned for all subsequent calls.
if ( ! did_action( 'current_screen' ) ) {
- _doing_it_wrong( __FUNCTION__, esc_html__( 'Current page retrieval should be called on or after the `current_screen` hook.', 'woocommerce' ), '0.16.0' );
+ _doing_it_wrong( __FUNCTION__, esc_html( 'Current page retrieval should be called on or after the `current_screen` hook.' ), '0.16.0' );
}
if ( is_null( $this->current_page ) ) {
diff --git a/plugins/woocommerce/src/Admin/Settings/SettingsSectionRegistry.php b/plugins/woocommerce/src/Admin/Settings/SettingsSectionRegistry.php
index 7f4bbbfc7ba..3943ece0803 100644
--- a/plugins/woocommerce/src/Admin/Settings/SettingsSectionRegistry.php
+++ b/plugins/woocommerce/src/Admin/Settings/SettingsSectionRegistry.php
@@ -67,7 +67,7 @@ final class SettingsSectionRegistry {
if ( '' === $parent_page_id || '' === $section_id ) {
wc_doing_it_wrong(
__METHOD__,
- esc_html__( 'Settings sections must declare a non-empty parent page id and section id.', 'woocommerce' ),
+ esc_html( 'Settings sections must declare a non-empty parent page id and section id.' ),
'10.9.0'
);
return false;
@@ -77,8 +77,7 @@ final class SettingsSectionRegistry {
wc_doing_it_wrong(
__METHOD__,
sprintf(
- /* translators: 1: parent settings page id, 2: settings section id. */
- esc_html__( 'A settings section is already registered for "%1$s/%2$s".', 'woocommerce' ),
+ esc_html( 'A settings section is already registered for "%1$s/%2$s".' ),
esc_html( $parent_page_id ),
esc_html( $section_id )
),
@@ -91,8 +90,7 @@ final class SettingsSectionRegistry {
wc_doing_it_wrong(
__METHOD__,
sprintf(
- /* translators: 1: parent settings page id, 2: settings section id. */
- esc_html__( 'The settings section "%1$s/%2$s" conflicts with an existing payment gateway section.', 'woocommerce' ),
+ esc_html( 'The settings section "%1$s/%2$s" conflicts with an existing payment gateway section.' ),
esc_html( $parent_page_id ),
esc_html( $section_id )
),
diff --git a/plugins/woocommerce/src/Blocks/Assets/AssetDataRegistry.php b/plugins/woocommerce/src/Blocks/Assets/AssetDataRegistry.php
index 9b5ead9e8be..6c764549488 100644
--- a/plugins/woocommerce/src/Blocks/Assets/AssetDataRegistry.php
+++ b/plugins/woocommerce/src/Blocks/Assets/AssetDataRegistry.php
@@ -428,7 +428,7 @@ class AssetDataRegistry {
protected function add_data( $key, $data ) {
if ( ! is_string( $key ) ) {
// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error
- trigger_error( esc_html__( 'Key for the data being registered must be a string', 'woocommerce' ), E_USER_WARNING );
+ trigger_error( esc_html( 'Key for the data being registered must be a string' ), E_USER_WARNING );
return;
}
if ( $this->exists( $key ) ) {
@@ -436,7 +436,7 @@ class AssetDataRegistry {
}
if ( isset( $this->data[ $key ] ) ) {
// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error
- trigger_error( esc_html__( 'Overriding existing data with an already registered key is not allowed', 'woocommerce' ), E_USER_WARNING );
+ trigger_error( esc_html( 'Overriding existing data with an already registered key is not allowed' ), E_USER_WARNING );
return;
}
if ( \is_callable( $data ) ) {
diff --git a/plugins/woocommerce/src/Blocks/BlockTypes/AbstractBlock.php b/plugins/woocommerce/src/Blocks/BlockTypes/AbstractBlock.php
index f318907c8e1..42383139b01 100644
--- a/plugins/woocommerce/src/Blocks/BlockTypes/AbstractBlock.php
+++ b/plugins/woocommerce/src/Blocks/BlockTypes/AbstractBlock.php
@@ -142,7 +142,7 @@ abstract class AbstractBlock {
*/
protected function initialize() {
if ( empty( $this->block_name ) ) {
- _doing_it_wrong( __METHOD__, esc_html__( 'Block name is required.', 'woocommerce' ), '4.5.0' );
+ _doing_it_wrong( __METHOD__, esc_html( 'Block name is required.' ), '4.5.0' );
return false;
}
$this->integration_registry->initialize( $this->block_name . '_block' );
diff --git a/plugins/woocommerce/src/Blocks/Integrations/IntegrationRegistry.php b/plugins/woocommerce/src/Blocks/Integrations/IntegrationRegistry.php
index 585b08c7ed9..1e56630f32a 100644
--- a/plugins/woocommerce/src/Blocks/Integrations/IntegrationRegistry.php
+++ b/plugins/woocommerce/src/Blocks/Integrations/IntegrationRegistry.php
@@ -32,7 +32,7 @@ class IntegrationRegistry {
}
if ( empty( $this->registry_identifier ) ) {
- _doing_it_wrong( __METHOD__, esc_html__( 'Integration registry requires an identifier.', 'woocommerce' ), '4.6.0' );
+ _doing_it_wrong( __METHOD__, esc_html( 'Integration registry requires an identifier.' ), '4.6.0' );
return false;
}
@@ -65,8 +65,7 @@ class IntegrationRegistry {
$name = $integration->get_name();
if ( $this->is_registered( $name ) ) {
- /* translators: %s: Integration name. */
- _doing_it_wrong( __METHOD__, esc_html( sprintf( __( '"%s" is already registered.', 'woocommerce' ), $name ) ), '4.6.0' );
+ _doing_it_wrong( __METHOD__, esc_html( sprintf( '"%s" is already registered.', $name ) ), '4.6.0' );
return false;
}
@@ -96,8 +95,7 @@ class IntegrationRegistry {
}
if ( ! $this->is_registered( $name ) ) {
- /* translators: %s: Integration name. */
- _doing_it_wrong( __METHOD__, esc_html( sprintf( __( 'Integration "%s" is not registered.', 'woocommerce' ), $name ) ), '4.6.0' );
+ _doing_it_wrong( __METHOD__, esc_html( sprintf( 'Integration "%s" is not registered.', $name ) ), '4.6.0' );
return false;
}
diff --git a/plugins/woocommerce/src/Blocks/Patterns/PatternRegistry.php b/plugins/woocommerce/src/Blocks/Patterns/PatternRegistry.php
index 5b33f43ff05..4dbabdb1079 100644
--- a/plugins/woocommerce/src/Blocks/Patterns/PatternRegistry.php
+++ b/plugins/woocommerce/src/Blocks/Patterns/PatternRegistry.php
@@ -43,8 +43,7 @@ class PatternRegistry {
'register_block_patterns',
esc_html(
sprintf(
- /* translators: %s: file name. */
- __( 'Could not register pattern "%s" as a block pattern ("Slug" field missing)', 'woocommerce' ),
+ 'Could not register pattern "%s" as a block pattern ("Slug" field missing)',
$source
)
),
@@ -58,8 +57,7 @@ class PatternRegistry {
'register_block_patterns',
esc_html(
sprintf(
- /* translators: %1s: file name; %2s: slug value found. */
- __( 'Could not register pattern "%1$s" as a block pattern (invalid slug "%2$s")', 'woocommerce' ),
+ 'Could not register pattern "%1$s" as a block pattern (invalid slug "%2$s")',
$source,
$pattern_data['slug']
)
@@ -79,8 +77,7 @@ class PatternRegistry {
'register_block_patterns',
esc_html(
sprintf(
- /* translators: %1s: file name; %2s: slug value found. */
- __( 'Could not register pattern "%s" as a block pattern ("Title" field missing)', 'woocommerce' ),
+ 'Could not register pattern "%s" as a block pattern ("Title" field missing)',
$source
)
),
diff --git a/plugins/woocommerce/src/Blocks/Utils/ProductGalleryUtils.php b/plugins/woocommerce/src/Blocks/Utils/ProductGalleryUtils.php
index 13878f6fc5c..cc7c6e9d068 100644
--- a/plugins/woocommerce/src/Blocks/Utils/ProductGalleryUtils.php
+++ b/plugins/woocommerce/src/Blocks/Utils/ProductGalleryUtils.php
@@ -16,7 +16,7 @@ class ProductGalleryUtils {
*/
public static function get_all_image_ids( $product ) {
if ( ! $product instanceof \WC_Product ) {
- wc_doing_it_wrong( __FUNCTION__, __( 'Invalid product object.', 'woocommerce' ), '9.8.0' );
+ wc_doing_it_wrong( __FUNCTION__, 'Invalid product object.', '9.8.0' );
return array();
}
@@ -65,7 +65,7 @@ class ProductGalleryUtils {
*/
public static function get_all_media_items( $product ) {
if ( ! $product instanceof \WC_Product ) {
- wc_doing_it_wrong( __FUNCTION__, __( 'Invalid product object.', 'woocommerce' ), '10.9.0' );
+ wc_doing_it_wrong( __FUNCTION__, 'Invalid product object.', '10.9.0' );
return array();
}
@@ -365,7 +365,7 @@ class ProductGalleryUtils {
$variation_image_ids = array();
if ( ! $product instanceof \WC_Product ) {
- wc_doing_it_wrong( __FUNCTION__, __( 'Invalid product object.', 'woocommerce' ), '9.8.0' );
+ wc_doing_it_wrong( __FUNCTION__, 'Invalid product object.', '9.8.0' );
return $variation_image_ids;
}
@@ -397,7 +397,7 @@ class ProductGalleryUtils {
$variation_gallery_data = array();
if ( ! $product instanceof \WC_Product ) {
- wc_doing_it_wrong( __FUNCTION__, __( 'Invalid product object.', 'woocommerce' ), '10.8.0' );
+ wc_doing_it_wrong( __FUNCTION__, 'Invalid product object.', '10.8.0' );
return $variation_gallery_data;
}
diff --git a/plugins/woocommerce/src/Internal/Admin/Orders/PageController.php b/plugins/woocommerce/src/Internal/Admin/Orders/PageController.php
index c1f705295fd..e716009f673 100644
--- a/plugins/woocommerce/src/Internal/Admin/Orders/PageController.php
+++ b/plugins/woocommerce/src/Internal/Admin/Orders/PageController.php
@@ -517,8 +517,7 @@ class PageController {
wc_doing_it_wrong(
__METHOD__,
sprintf(
- // translators: %s is the name of a function.
- esc_html__( '%s must be called after the current_screen action.', 'woocommerce' ),
+ esc_html( '%s must be called after the current_screen action.' ),
esc_html( __METHOD__ )
),
'7.9.0'
@@ -532,8 +531,7 @@ class PageController {
wc_doing_it_wrong(
__METHOD__,
sprintf(
- // translators: %s is the name of an order type.
- esc_html__( '%s is not a valid order type.', 'woocommerce' ),
+ esc_html( '%s is not a valid order type.' ),
esc_html( $type )
),
'7.9.0'
diff --git a/plugins/woocommerce/src/Internal/Admin/Settings/PaymentsProviders.php b/plugins/woocommerce/src/Internal/Admin/Settings/PaymentsProviders.php
index ef6cd703876..ae20c434c28 100644
--- a/plugins/woocommerce/src/Internal/Admin/Settings/PaymentsProviders.php
+++ b/plugins/woocommerce/src/Internal/Admin/Settings/PaymentsProviders.php
@@ -408,8 +408,7 @@ class PaymentsProviders {
wc_doing_it_wrong(
__METHOD__,
sprintf(
- /* translators: %s: Gateway ID. */
- esc_html__( 'The provider class for gateway ID "%s" must extend the PaymentGateway class.', 'woocommerce' ),
+ esc_html( 'The provider class for gateway ID "%s" must extend the PaymentGateway class.' ),
$gateway_id
),
'10.4.0'
@@ -456,8 +455,7 @@ class PaymentsProviders {
wc_doing_it_wrong(
__METHOD__,
sprintf(
- /* translators: %s: Payment extension suggestion ID. */
- esc_html__( 'The provider class for payment extension suggestion ID "%s" must extend the PaymentGateway class.', 'woocommerce' ),
+ esc_html( 'The provider class for payment extension suggestion ID "%s" must extend the PaymentGateway class.' ),
$pes_id
),
'10.4.0'
diff --git a/plugins/woocommerce/src/Internal/Admin/Settings/SettingsUIRequestContext.php b/plugins/woocommerce/src/Internal/Admin/Settings/SettingsUIRequestContext.php
index 071f1a839ea..b1520ce40d1 100644
--- a/plugins/woocommerce/src/Internal/Admin/Settings/SettingsUIRequestContext.php
+++ b/plugins/woocommerce/src/Internal/Admin/Settings/SettingsUIRequestContext.php
@@ -390,8 +390,7 @@ class SettingsUIRequestContext {
$this->record_script_handles_failure(
new \RuntimeException(
sprintf(
- /* translators: %s: script handle. */
- __( 'Settings UI script handle "%s" could not be enqueued.', 'woocommerce' ),
+ 'Settings UI script handle "%s" could not be enqueued.',
sanitize_text_field( $script_handle )
)
),
@@ -446,7 +445,7 @@ class SettingsUIRequestContext {
return '' !== $this->script_handles_failure_reason
? $this->script_handles_failure_reason
- : __( 'Settings UI script handles could not be resolved.', 'woocommerce' );
+ : 'Settings UI script handles could not be resolved.';
}
/**
@@ -495,7 +494,7 @@ class SettingsUIRequestContext {
return '' !== $this->schema_failure_reason
? $this->schema_failure_reason
- : __( 'Settings UI schema could not be resolved.', 'woocommerce' );
+ : 'Settings UI schema could not be resolved.';
}
/**
@@ -566,8 +565,7 @@ class SettingsUIRequestContext {
wc_doing_it_wrong(
__METHOD__,
sprintf(
- /* translators: 1: settings page id, 2: settings section id, 3: failure reason. */
- esc_html__( 'The native Settings UI page for page "%1$s" section "%2$s" could not be resolved. Falling back to the default settings adapter. Reason: %3$s', 'woocommerce' ),
+ esc_html( 'The native Settings UI page for page "%1$s" section "%2$s" could not be resolved. Falling back to the default settings adapter. Reason: %3$s' ),
esc_html( $settings_page->get_id() ),
esc_html( self::get_section_key( $section ) ),
esc_html( get_class( $e ) . ': ' . $e->getMessage() )
@@ -610,15 +608,11 @@ class SettingsUIRequestContext {
* @throws \InvalidArgumentException When a handle is not a non-empty string.
*/
private static function validate_script_handles( array $script_handles ): array {
- // Exception messages are cached diagnostics rather than HTML output. Dynamic
- // handles are sanitized before the exception crosses this boundary.
- // phpcs:disable WordPress.Security.EscapeOutput.ExceptionNotEscaped
foreach ( $script_handles as $script_handle ) {
if ( ! is_string( $script_handle ) || '' === trim( $script_handle ) ) {
- throw new \InvalidArgumentException( __( 'Settings UI script handles must be non-empty strings.', 'woocommerce' ) );
+ throw new \InvalidArgumentException( 'Settings UI script handles must be non-empty strings.' );
}
}
- // phpcs:enable WordPress.Security.EscapeOutput.ExceptionNotEscaped
return array_values( array_unique( array_map( 'trim', $script_handles ) ) );
}
@@ -646,8 +640,7 @@ class SettingsUIRequestContext {
$this->record_script_handles_failure(
new \RuntimeException(
sprintf(
- /* translators: %s: script handle. */
- __( 'Settings UI script handle "%s" is not registered.', 'woocommerce' ),
+ 'Settings UI script handle "%s" is not registered.',
sanitize_text_field( $script_handle )
)
),
@@ -672,8 +665,7 @@ class SettingsUIRequestContext {
self::log_resolution_failure( 'Settings UI script handles', $this->settings_page->get_id(), $this->section, $e, $caller );
$this->script_handles_failure_reason = sprintf(
- /* translators: %s: failure reason. */
- __( 'Settings UI script handles could not be resolved: %s', 'woocommerce' ),
+ 'Settings UI script handles could not be resolved: %s',
self::sanitize_failure_reason( $e )
);
}
diff --git a/plugins/woocommerce/src/Internal/Admin/Settings/SettingsUISchema.php b/plugins/woocommerce/src/Internal/Admin/Settings/SettingsUISchema.php
index b3cc9097194..b7f0d52b38b 100644
--- a/plugins/woocommerce/src/Internal/Admin/Settings/SettingsUISchema.php
+++ b/plugins/woocommerce/src/Internal/Admin/Settings/SettingsUISchema.php
@@ -340,8 +340,7 @@ class SettingsUISchema {
self::emit_conversion_notice(
__METHOD__,
$converted_fields,
- /* translators: %s: comma-separated field ids. */
- __( 'A Settings UI schema provider supplied non-string option, field, or visibility values that WooCommerce converted for compatibility: %s. Update the provider to supply string values.', 'woocommerce' ),
+ 'A Settings UI schema provider supplied non-string option, field, or visibility values that WooCommerce converted for compatibility: %s. Update the provider to supply string values.',
'11.0.0'
);
@@ -549,8 +548,7 @@ class SettingsUISchema {
self::emit_conversion_notice(
self::class . '::canonicalize_schema_values',
$converted_fields,
- /* translators: %s: comma-separated field ids. */
- __( 'A Settings UI schema provider supplied legacy field values or metadata that WooCommerce converted for compatibility: %s. Update the provider to supply canonical values.', 'woocommerce' ),
+ 'A Settings UI schema provider supplied legacy field values or metadata that WooCommerce converted for compatibility: %s. Update the provider to supply canonical values.',
'11.2.0'
);
}
@@ -1328,7 +1326,7 @@ class SettingsUISchema {
*
* @param string $method Method name reported by the notice.
* @param string[] $field_ids Affected field ids.
- * @param string $message Translatable sprintf message.
+ * @param string $message English sprintf message with one %s placeholder for the field ids.
* @param string $version Version when the notice was introduced.
*/
private static function emit_conversion_notice( string $method, array $field_ids, string $message, string $version ): void {
@@ -1339,7 +1337,6 @@ class SettingsUISchema {
wc_doing_it_wrong(
$method,
sprintf(
- /* translators: %s: comma-separated field ids. */
esc_html( $message ),
esc_html( implode( ', ', array_unique( $field_ids ) ) )
),
diff --git a/plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableDataStore.php b/plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableDataStore.php
index 043e1403df0..a72ee202067 100644
--- a/plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableDataStore.php
+++ b/plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableDataStore.php
@@ -2430,8 +2430,7 @@ FROM $order_meta_table
$taxonomy_obj = get_taxonomy( $taxonomy );
if ( ! $taxonomy_obj ) {
- /* translators: %s: Taxonomy name. */
- _doing_it_wrong( __FUNCTION__, esc_html( sprintf( __( 'Invalid taxonomy: %s.', 'woocommerce' ), $taxonomy ) ), '7.9.0' );
+ _doing_it_wrong( __FUNCTION__, esc_html( sprintf( 'Invalid taxonomy: %s.', $taxonomy ) ), '7.9.0' );
continue;
}
diff --git a/plugins/woocommerce/src/Internal/Features/FeaturesController.php b/plugins/woocommerce/src/Internal/Features/FeaturesController.php
index 262cd796e50..c80529bbb65 100644
--- a/plugins/woocommerce/src/Internal/Features/FeaturesController.php
+++ b/plugins/woocommerce/src/Internal/Features/FeaturesController.php
@@ -306,7 +306,7 @@ class FeaturesController {
$this->issued_feature_definitions_notice = true;
wc_doing_it_wrong(
__METHOD__,
- __( 'FeaturesController methods that access feature definitions should not be called while feature definitions are being initialized. Use the woocommerce_init action or later.', 'woocommerce' ),
+ 'FeaturesController methods that access feature definitions should not be called while feature definitions are being initialized. Use the woocommerce_init action or later.',
'11.3.0'
);
}
@@ -1021,8 +1021,7 @@ class FeaturesController {
public function declare_compatibility( string $feature_id, string $plugin_file, bool $positive_compatibility = true ): bool {
if ( ! $this->proxy->call_function( 'doing_action', 'before_woocommerce_init' ) ) {
$class_and_method = ( new \ReflectionClass( $this ) )->getShortName() . '::' . __FUNCTION__;
- /* translators: 1: class::method 2: before_woocommerce_init */
- $this->proxy->call_function( 'wc_doing_it_wrong', $class_and_method, sprintf( __( '%1$s should be called inside the %2$s action.', 'woocommerce' ), $class_and_method, 'before_woocommerce_init' ), '7.0' );
+ $this->proxy->call_function( 'wc_doing_it_wrong', $class_and_method, sprintf( '%1$s should be called inside the %2$s action.', $class_and_method, 'before_woocommerce_init' ), '7.0' );
return false;
}
if ( ! $this->feature_exists( $feature_id ) ) {
@@ -1230,8 +1229,7 @@ class FeaturesController {
! $this->proxy->call_function( 'doing_action', 'woocommerce_init' ) ) {
if ( ! is_null( $function_name ) ) {
$class_and_method = ( new \ReflectionClass( $this ) )->getShortName() . '::' . $function_name;
- /* translators: 1: class::method 2: plugins_loaded */
- $this->proxy->call_function( 'wc_doing_it_wrong', $class_and_method, sprintf( __( '%1$s should not be called before the %2$s action.', 'woocommerce' ), $class_and_method, 'woocommerce_init' ), '7.0' );
+ $this->proxy->call_function( 'wc_doing_it_wrong', $class_and_method, sprintf( '%1$s should not be called before the %2$s action.', $class_and_method, 'woocommerce_init' ), '7.0' );
}
return false;
}
diff --git a/plugins/woocommerce/src/Internal/MCP/McpEndpointRemoval.php b/plugins/woocommerce/src/Internal/MCP/McpEndpointRemoval.php
index ec2e748b0bb..fe24c645e2f 100644
--- a/plugins/woocommerce/src/Internal/MCP/McpEndpointRemoval.php
+++ b/plugins/woocommerce/src/Internal/MCP/McpEndpointRemoval.php
@@ -299,8 +299,7 @@ class McpEndpointRemoval {
wc_doing_it_wrong(
$function_name,
sprintf(
- /* translators: 1: Function or method name, 2: WooCommerce version, 3: Documentation URL. */
- __( '%1$s was removed in WooCommerce %2$s along with the WooCommerce MCP endpoint and its REST-based abilities. WooCommerce abilities remain available through the WordPress Abilities API, and the MCP Adapter plugin exposes them to MCP clients. See %3$s.', 'woocommerce' ),
+ '%1$s was removed in WooCommerce %2$s along with the WooCommerce MCP endpoint and its REST-based abilities. WooCommerce abilities remain available through the WordPress Abilities API, and the MCP Adapter plugin exposes them to MCP clients. See %3$s.',
$function_name,
self::REMOVED_IN,
self::DOCS_URL
diff --git a/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Fulfillments/Controller.php b/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Fulfillments/Controller.php
index 5734e12f35f..c5b2fcde551 100644
--- a/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Fulfillments/Controller.php
+++ b/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Fulfillments/Controller.php
@@ -511,7 +511,7 @@ class Controller extends AbstractController {
if ( ! is_array( $providers ) ) {
_doing_it_wrong(
'woocommerce_rest_prepare_fulfillments_providers',
- esc_html__( 'The filter must return an array of providers.', 'woocommerce' ),
+ esc_html( 'The filter must return an array of providers.' ),
'10.5.0'
);
$providers = array();
@@ -554,7 +554,7 @@ class Controller extends AbstractController {
if ( $has_invalid ) {
_doing_it_wrong(
'woocommerce_rest_prepare_fulfillments_providers',
- esc_html__( 'Some providers were removed because they are missing required keys (label, icon, value, url).', 'woocommerce' ),
+ esc_html( 'Some providers were removed because they are missing required keys (label, icon, value, url).' ),
'10.5.0'
);
}
diff --git a/plugins/woocommerce/src/Internal/Utilities/FilesystemUtil.php b/plugins/woocommerce/src/Internal/Utilities/FilesystemUtil.php
index 1c88c00761d..ddcc15e3c25 100644
--- a/plugins/woocommerce/src/Internal/Utilities/FilesystemUtil.php
+++ b/plugins/woocommerce/src/Internal/Utilities/FilesystemUtil.php
@@ -106,7 +106,7 @@ class FilesystemUtil {
_doing_it_wrong(
__METHOD__,
- esc_html__( 'WP_Filesystem_Direct could not be loaded. Falling back to the configured FS_METHOD; operations on the uploads directory may fail if FS_METHOD is misconfigured.', 'woocommerce' ),
+ esc_html( 'WP_Filesystem_Direct could not be loaded. Falling back to the configured FS_METHOD; operations on the uploads directory may fail if FS_METHOD is misconfigured.' ),
'11.0.0'
);
diff --git a/plugins/woocommerce/src/Internal/Utilities/HtmlSanitizer.php b/plugins/woocommerce/src/Internal/Utilities/HtmlSanitizer.php
index 4924e2f4ee4..8f500164e25 100644
--- a/plugins/woocommerce/src/Internal/Utilities/HtmlSanitizer.php
+++ b/plugins/woocommerce/src/Internal/Utilities/HtmlSanitizer.php
@@ -90,7 +90,7 @@ class HtmlSanitizer {
private function apply_string_callbacks( array $callbacks, string $string ): string {
foreach ( $callbacks as $callback ) {
if ( ! is_callable( $callback ) ) {
- _doing_it_wrong( __CLASS__ . '::apply', esc_html__( 'String processors must be an array of valid callbacks.', 'woocommerce' ), esc_html( WC()->version ) );
+ _doing_it_wrong( __CLASS__ . '::apply', esc_html( 'String processors must be an array of valid callbacks.' ), esc_html( WC()->version ) );
return '';
}
diff --git a/plugins/woocommerce/src/Packages.php b/plugins/woocommerce/src/Packages.php
index 45d1b52c120..7f65303265d 100644
--- a/plugins/woocommerce/src/Packages.php
+++ b/plugins/woocommerce/src/Packages.php
@@ -337,10 +337,9 @@ class Packages {
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
error_log( // phpcs:ignore
sprintf(
- /* Translators: %s package name. */
- esc_html__( 'Missing the WooCommerce %s package', 'woocommerce' ),
+ esc_html( 'Missing the WooCommerce %s package' ),
'<code>' . esc_html( $package ) . '</code>'
- ) . ' - ' . esc_html__( 'Your installation of WooCommerce is incomplete. If you installed WooCommerce from GitHub, please refer to this document to set up your development environment: https://developer.woocommerce.com/docs/contribution/contributing/#setting-up-your-development-environment', 'woocommerce' )
+ ) . ' - ' . esc_html( 'Your installation of WooCommerce is incomplete. If you installed WooCommerce from GitHub, please refer to this document to set up your development environment: https://developer.woocommerce.com/docs/contribution/contributing/#setting-up-your-development-environment' )
);
}
add_action(
diff --git a/plugins/woocommerce/tests/Tools/phpcs/README.md b/plugins/woocommerce/tests/Tools/phpcs/README.md
index 66c0052363f..00f70d2a370 100644
--- a/plugins/woocommerce/tests/Tools/phpcs/README.md
+++ b/plugins/woocommerce/tests/Tools/phpcs/README.md
@@ -48,9 +48,45 @@ flagged and allowed cases. Run the sniff over it directly:
```sh
cd plugins/woocommerce
-bin/composer/phpcs/vendor/bin/phpcs -s \
+vendor/bin/phpcs -s \
--standard=tests/Tools/phpcs/WooCommerceInternal/ruleset.xml \
tests/Tools/phpcs/WooCommerceInternal/Tests/DB/IdentifierPlaceholderUnitTest.inc
```
Only the two unguarded `%i` cases (cases 1 and 2) should be reported.
+
+## `WooCommerceInternal.I18n.DiagnosticMessage`
+
+Flags a WordPress translation call (`__()`, `esc_html__()`, `_n()` and the rest) inside the message passed to a developer diagnostic: `wc_doing_it_wrong()`, `_doing_it_wrong()`, `trigger_error()`, `wp_trigger_error()`, `user_error()`, `error_log()`, and the replacement or message of the deprecation notices (`wc_deprecated_*()`, `_deprecated_*()`, `apply_filters_deprecated()`, `do_action_deprecated()`, `wc_do_deprecated_action()`). Calls made through `LegacyProxy`, such as `$this->proxy->call_function( 'wc_doing_it_wrong', ... )`, are checked too.
+
+These messages are read in logs, filtered by monitoring tools, and searched by developers and support. A translated message reads differently on every site language, so a log filter or a search for the English text misses it. PHP's own errors are English for the same reason.
+
+**How to satisfy the sniff:** pass the English string directly. Keep any escaping the message had, without the translation:
+
+```php
+wc_doing_it_wrong( __FUNCTION__, 'This function should not be called before woocommerce_init.', '2.3' );
+
+wc_doing_it_wrong(
+ __METHOD__,
+ sprintf( esc_html( 'A settings section is already registered for "%s".' ), esc_html( $section_id ) ),
+ '10.9.0'
+);
+```
+
+WordPress still translates its own wrapper around these messages (for example "Function %1$s was called incorrectly."), so only the WooCommerce part of a PHP notice is guaranteed to be English. Strings shown to merchants or shoppers stay translated, even when an error causes them.
+
+The sniff only sees translation calls written inside the diagnostic call. It does not follow a translated string built elsewhere and passed in through a variable, a property or a wrapper method, so keep those English by hand.
+
+### Verifying the sniff
+
+The fixture `WooCommerceInternal/Tests/I18n/DiagnosticMessageUnitTest.inc` documents the flagged and allowed cases:
+
+```sh
+cd plugins/woocommerce
+vendor/bin/phpcs -s \
+ --standard=tests/Tools/phpcs/WooCommerceInternal/ruleset.xml \
+ --sniffs=WooCommerceInternal.I18n.DiagnosticMessage \
+ tests/Tools/phpcs/WooCommerceInternal/Tests/I18n/DiagnosticMessageUnitTest.inc
+```
+
+Only cases 1 to 6, 12 and 13 should be reported, one error each.
diff --git a/plugins/woocommerce/tests/Tools/phpcs/WooCommerceInternal/Sniffs/I18n/DiagnosticMessageSniff.php b/plugins/woocommerce/tests/Tools/phpcs/WooCommerceInternal/Sniffs/I18n/DiagnosticMessageSniff.php
new file mode 100644
index 00000000000..78abbd5fa68
--- /dev/null
+++ b/plugins/woocommerce/tests/Tools/phpcs/WooCommerceInternal/Sniffs/I18n/DiagnosticMessageSniff.php
@@ -0,0 +1,216 @@
+<?php
+/**
+ * DiagnosticMessageSniff.
+ *
+ * @package WooCommerce\Tests\Tools\PHPCS
+ */
+
+declare( strict_types=1 );
+
+namespace WooCommerceInternal\Sniffs\I18n;
+
+use PHP_CodeSniffer\Util\Tokens;
+use PHPCSUtils\Utils\PassedParameters;
+use WordPressCS\WordPress\AbstractFunctionParameterSniff;
+
+/**
+ * Flags translation calls inside the message passed to a developer diagnostic function.
+ *
+ * Messages for `wc_doing_it_wrong()`, `trigger_error()`, `error_log()` and the deprecation
+ * notices are read in logs and searched by developers and support. Translating them makes the
+ * same problem appear under a different text on every site language, so they stay in English.
+ * Calls made through `LegacyProxy::call_function( 'wc_doing_it_wrong', ... )` are checked too.
+ * The sniff only sees translation calls written inside the call, not values built elsewhere.
+ */
+class DiagnosticMessageSniff extends AbstractFunctionParameterSniff {
+
+ /**
+ * Group name for this sniff's functions.
+ *
+ * @var string
+ */
+ protected $group_name = 'diagnostic_message';
+
+ /**
+ * Diagnostic functions, mapped to the position and name of each parameter that holds message text.
+ *
+ * @var array<string, array<int, string>>
+ */
+ protected $target_functions = array(
+ 'wc_doing_it_wrong' => array( 2 => 'message' ),
+ '_doing_it_wrong' => array( 2 => 'message' ),
+ 'trigger_error' => array( 1 => 'message' ),
+ 'wp_trigger_error' => array( 2 => 'message' ),
+ 'user_error' => array( 1 => 'message' ),
+ 'error_log' => array( 1 => 'message' ),
+ 'wc_deprecated_function' => array( 3 => 'replacement' ),
+ '_deprecated_function' => array( 3 => 'replacement' ),
+ '_deprecated_class' => array( 3 => 'replacement' ),
+ 'wc_deprecated_argument' => array( 3 => 'message' ),
+ '_deprecated_argument' => array( 3 => 'message' ),
+ 'wc_deprecated_hook' => array(
+ 3 => 'replacement',
+ 4 => 'message',
+ ),
+ '_deprecated_hook' => array(
+ 3 => 'replacement',
+ 4 => 'message',
+ ),
+ '_deprecated_file' => array(
+ 3 => 'replacement',
+ 4 => 'message',
+ ),
+ 'apply_filters_deprecated' => array(
+ 4 => 'replacement',
+ 5 => 'message',
+ ),
+ 'do_action_deprecated' => array(
+ 4 => 'replacement',
+ 5 => 'message',
+ ),
+ 'wc_do_deprecated_action' => array(
+ 4 => 'replacement',
+ 5 => 'message',
+ ),
+ // LegacyProxy::call_function(); the proxied function name decides what to check.
+ 'call_function' => array(),
+ );
+
+ /**
+ * WordPress functions that return or print translated text.
+ *
+ * @var array<string, true>
+ */
+ private const TRANSLATION_FUNCTIONS = array(
+ '__' => true,
+ '_e' => true,
+ '_x' => true,
+ '_ex' => true,
+ '_n' => true,
+ '_nx' => true,
+ 'esc_html__' => true,
+ 'esc_html_e' => true,
+ 'esc_html_x' => true,
+ 'esc_attr__' => true,
+ 'esc_attr_e' => true,
+ 'esc_attr_x' => true,
+ 'translate' => true,
+ 'translate_with_gettext_context' => true,
+ 'translate_nooped_plural' => true,
+ );
+
+ /**
+ * Also matches `->call_function()` and `::call_function()`, the LegacyProxy call style.
+ *
+ * @param int $stackPtr The position of the current token in the stack.
+ * @return bool
+ */
+ public function is_targetted_token( $stackPtr ) {
+ if ( 'call_function' !== strtolower( $this->tokens[ $stackPtr ]['content'] ) ) {
+ return parent::is_targetted_token( $stackPtr );
+ }
+
+ $prev = $this->phpcsFile->findPrevious( Tokens::$emptyTokens, $stackPtr - 1, null, true );
+ $next = $this->phpcsFile->findNext( Tokens::$emptyTokens, $stackPtr + 1, null, true );
+
+ return false !== $prev && false !== $next
+ && in_array( $this->tokens[ $prev ]['code'], array( \T_OBJECT_OPERATOR, \T_NULLSAFE_OBJECT_OPERATOR, \T_DOUBLE_COLON ), true )
+ && \T_OPEN_PARENTHESIS === $this->tokens[ $next ]['code']
+ && isset( $this->tokens[ $next ]['parenthesis_closer'] );
+ }
+
+ /**
+ * Flags translation calls in the message parameters of a matched diagnostic call.
+ *
+ * @param int $stackPtr The position of the function name token.
+ * @param string $group_name The matched group name.
+ * @param string $matched_content The matched function name, in lowercase.
+ * @param array $parameters The call's parameters, from PassedParameters::getParameters().
+ * @return void
+ */
+ public function process_parameters( $stackPtr, $group_name, $matched_content, $parameters ) {
+ if ( 'call_function' === $matched_content ) {
+ $this->process_proxied_call( $parameters );
+ return;
+ }
+
+ foreach ( $this->target_functions[ $matched_content ] as $position => $name ) {
+ $parameter = PassedParameters::getParameterFromStack( $parameters, $position, $name );
+ if ( false !== $parameter ) {
+ $this->flag_translations( $parameter, $matched_content );
+ }
+ }
+ }
+
+ /**
+ * Checks `call_function( 'wc_doing_it_wrong', ... )`, where every argument is shifted by one.
+ *
+ * @param array $parameters The call's parameters, from PassedParameters::getParameters().
+ * @return void
+ */
+ private function process_proxied_call( array $parameters ): void {
+ if ( ! isset( $parameters[1] ) ) {
+ return;
+ }
+
+ $first = $this->phpcsFile->findNext( Tokens::$emptyTokens, $parameters[1]['start'], $parameters[1]['end'] + 1, true );
+ if ( false === $first || \T_CONSTANT_ENCAPSED_STRING !== $this->tokens[ $first ]['code'] ) {
+ return;
+ }
+
+ $function = strtolower( trim( $this->tokens[ $first ]['content'], '\'"' ) );
+ if ( 'call_function' === $function || ! isset( $this->target_functions[ $function ] ) ) {
+ return;
+ }
+
+ foreach ( array_keys( $this->target_functions[ $function ] ) as $position ) {
+ if ( isset( $parameters[ $position + 1 ] ) ) {
+ $this->flag_translations( $parameters[ $position + 1 ], $function );
+ }
+ }
+ }
+
+ /**
+ * Reports each translation call inside one parameter.
+ *
+ * @param array $parameter One parameter, from PassedParameters.
+ * @param string $diagnostic The diagnostic function receiving it.
+ * @return void
+ */
+ private function flag_translations( array $parameter, string $diagnostic ): void {
+ for ( $i = $parameter['start']; $i <= $parameter['end']; $i++ ) {
+ if ( \T_STRING !== $this->tokens[ $i ]['code'] ) {
+ continue;
+ }
+
+ $function = strtolower( $this->tokens[ $i ]['content'] );
+ if ( ! isset( self::TRANSLATION_FUNCTIONS[ $function ] ) || ! $this->is_function_call( $i ) ) {
+ continue;
+ }
+
+ $this->phpcsFile->addError(
+ 'Developer diagnostic messages must not be translated. Pass an English string to %s() instead of calling %s(), so the message is the same in every site language.',
+ $i,
+ 'Translated',
+ array( $diagnostic, $function )
+ );
+ }
+ }
+
+ /**
+ * Determines whether a T_STRING token is a call to a global function rather than a method call.
+ *
+ * @param int $ptr Position of the T_STRING token.
+ * @return bool
+ */
+ private function is_function_call( int $ptr ): bool {
+ $next = $this->phpcsFile->findNext( Tokens::$emptyTokens, $ptr + 1, null, true );
+ if ( false === $next || \T_OPEN_PARENTHESIS !== $this->tokens[ $next ]['code'] ) {
+ return false;
+ }
+
+ $prev = $this->phpcsFile->findPrevious( Tokens::$emptyTokens, $ptr - 1, null, true );
+
+ return false === $prev || ! in_array( $this->tokens[ $prev ]['code'], array( \T_OBJECT_OPERATOR, \T_NULLSAFE_OBJECT_OPERATOR, \T_DOUBLE_COLON, \T_FUNCTION ), true );
+ }
+}
diff --git a/plugins/woocommerce/tests/Tools/phpcs/WooCommerceInternal/Tests/I18n/DiagnosticMessageUnitTest.inc b/plugins/woocommerce/tests/Tools/phpcs/WooCommerceInternal/Tests/I18n/DiagnosticMessageUnitTest.inc
new file mode 100644
index 00000000000..2d23f2ddd75
--- /dev/null
+++ b/plugins/woocommerce/tests/Tools/phpcs/WooCommerceInternal/Tests/I18n/DiagnosticMessageUnitTest.inc
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Fixture for DiagnosticMessageSniff.
+ *
+ * Each numbered case documents whether the sniff should flag it.
+ *
+ * @package WooCommerce\Tests\Tools\PHPCS
+ */
+
+// Case 1: translated message — FLAGGED.
+wc_doing_it_wrong( __FUNCTION__, __( 'Do not call this yet.', 'woocommerce' ), '1.0.0' );
+
+// Case 2: escaped translation nested in sprintf() across lines — FLAGGED.
+_doing_it_wrong(
+ __METHOD__,
+ sprintf(
+ esc_html__( 'Item "%s" is already registered.', 'woocommerce' ),
+ esc_html( $name )
+ ),
+ '1.0.0'
+);
+
+// Case 3: plural translation in trigger_error() — FLAGGED.
+trigger_error( sprintf( _n( '%d item failed.', '%d items failed.', $count, 'woocommerce' ), $count ), E_USER_WARNING );
+
+// Case 4: translated replacement in a deprecation notice, namespaced call — FLAGGED.
+\_deprecated_function( __METHOD__, '1.0.0', _x( 'Use the new API.', 'deprecation', 'woocommerce' ) );
+
+// Case 5: translated message passed by name — FLAGGED.
+error_log( message: __( 'Missing package.', 'woocommerce' ) );
+
+// Case 6: translated message in a deprecated hook dispatch — FLAGGED.
+do_action_deprecated( 'old_hook', array( $value ), '1.0.0', 'new_hook', esc_html__( 'Use new_hook.', 'woocommerce' ) );
+
+// Case 7: English messages, escaped or not — NOT flagged.
+wc_doing_it_wrong( __FUNCTION__, 'Do not call this yet.', '1.0.0' );
+_doing_it_wrong( __METHOD__, sprintf( esc_html( 'Item "%s" is already registered.' ), esc_html( $name ) ), '1.0.0' );
+
+// Case 8: translated hook arguments, not the deprecation message — NOT flagged.
+apply_filters_deprecated( 'old_filter', array( __( 'Label', 'woocommerce' ) ), '1.0.0', 'new_filter' );
+
+// Case 9: method calls and function declarations sharing a name — NOT flagged.
+$this->doing_it_wrong( __( 'Handled by the method author.', 'woocommerce' ) );
+$logger->error_log( __( 'Not the PHP function.', 'woocommerce' ) );
+
+// Case 10: translation outside the diagnostic call — NOT flagged.
+$label = __( 'Save changes', 'woocommerce' );
+wc_doing_it_wrong( __FUNCTION__, 'Uses a separate label.', '1.0.0' );
+
+// Case 11: translation function names inside strings and comments — NOT flagged.
+wc_doing_it_wrong( __FUNCTION__, 'Avoid calling __() here.', /* __( 'x' ) */ '1.0.0' );
+
+// Case 12: translated message through LegacyProxy::call_function() — FLAGGED.
+$this->proxy->call_function( 'wc_doing_it_wrong', __METHOD__, sprintf( __( '%s should be called later.', 'woocommerce' ), __METHOD__ ), '1.0.0' );
+
+// Case 13: translated message in wp_trigger_error() — FLAGGED.
+wp_trigger_error( __FUNCTION__, esc_html__( 'Something went wrong.', 'woocommerce' ) );
+
+// Case 14: LegacyProxy calls that are English, or that proxy a non-diagnostic function — NOT flagged.
+$this->proxy->call_function( 'wc_doing_it_wrong', __METHOD__, 'Should be called later.', '1.0.0' );
+$this->proxy->call_function( 'wc_add_notice', __( 'Saved.', 'woocommerce' ) );
diff --git a/plugins/woocommerce/tests/Tools/phpcs/WooCommerceInternal/ruleset.xml b/plugins/woocommerce/tests/Tools/phpcs/WooCommerceInternal/ruleset.xml
index 5af186b2120..33fd59ad2ca 100644
--- a/plugins/woocommerce/tests/Tools/phpcs/WooCommerceInternal/ruleset.xml
+++ b/plugins/woocommerce/tests/Tools/phpcs/WooCommerceInternal/ruleset.xml
@@ -3,4 +3,5 @@
<description>Local WooCommerce Core PHPCS sniffs. Used standalone to verify the sniffs against their fixtures; the sniffs are wired into the main ruleset from plugins/woocommerce/phpcs.xml.</description>
<rule ref="./Sniffs/DB/IdentifierPlaceholderSniff.php" />
+ <rule ref="./Sniffs/I18n/DiagnosticMessageSniff.php" />
</ruleset>
diff --git a/plugins/woocommerce/tests/php/includes/data-stores/class-wc-order-data-store-cpt-test.php b/plugins/woocommerce/tests/php/includes/data-stores/class-wc-order-data-store-cpt-test.php
index 2a9bc941b14..6abe72b993d 100644
--- a/plugins/woocommerce/tests/php/includes/data-stores/class-wc-order-data-store-cpt-test.php
+++ b/plugins/woocommerce/tests/php/includes/data-stores/class-wc-order-data-store-cpt-test.php
@@ -1703,4 +1703,40 @@ class WC_Order_Data_Store_CPT_Test extends WC_Unit_Test_Case {
$this->assertGreaterThan( 0, $item->get_product_id(), 'Item should have a product ID from cached meta' );
}
}
+
+ /**
+ * @testdox Unsupported order query arguments are reported in English, with the singular or plural wording for their count, whatever the site language.
+ *
+ * @testWith [["meta_query"], "Order query argument (meta_query) is not supported on the current order datastore."]
+ * [["meta_query", "field_query"], "Order query arguments (meta_query, field_query) are not supported on the current order datastore."]
+ *
+ * @param string[] $unsupported_args Unsupported query arguments to pass.
+ * @param string $expected_message Expected start of the diagnostic message.
+ */
+ public function test_query_reports_unsupported_args_in_english( array $unsupported_args, string $expected_message ): void {
+ $this->setExpectedIncorrectUsage( WC_Order_Data_Store_CPT::class . '::query' );
+ add_filter(
+ 'ngettext',
+ function ( $translation, $single, $plural, $number, $domain ) {
+ return 'woocommerce' === $domain ? 'Übersetzt: ' . ( 1 === $number ? $single : $plural ) : $translation;
+ },
+ 10,
+ 5
+ );
+ $messages = array();
+ add_action(
+ 'doing_it_wrong_run',
+ function ( $function_name, $message ) use ( &$messages ) {
+ $messages[ $function_name ] = $message;
+ },
+ 10,
+ 2
+ );
+
+ $query_vars = array_fill_keys( $unsupported_args, array( array( 'key' => '_unsupported_probe' ) ) );
+ ( new WC_Order_Data_Store_CPT() )->query( $query_vars );
+
+ $this->assertArrayHasKey( WC_Order_Data_Store_CPT::class . '::query', $messages, 'Unsupported arguments should raise a notice.' );
+ $this->assertStringStartsWith( $expected_message, $messages[ WC_Order_Data_Store_CPT::class . '::query' ], 'The notice should use the English wording for the argument count.' );
+ }
}
diff --git a/plugins/woocommerce/tests/php/includes/wc-product-functions-test.php b/plugins/woocommerce/tests/php/includes/wc-product-functions-test.php
index d2861406113..b148f1000ab 100644
--- a/plugins/woocommerce/tests/php/includes/wc-product-functions-test.php
+++ b/plugins/woocommerce/tests/php/includes/wc-product-functions-test.php
@@ -1736,9 +1736,18 @@ class WC_Product_Functions_Tests extends \WC_Unit_Test_Case {
}
/**
- * @testdox Product category list warns about an unsupported ordering mode and still falls back to WordPress order.
+ * @testdox Product category list warns in English about an unsupported ordering mode and still falls back to WordPress order.
*/
public function test_wc_get_product_category_list_warns_on_unsupported_orderby(): void {
+ $messages = array();
+ add_action(
+ 'doing_it_wrong_run',
+ function ( $function_name, $message ) use ( &$messages ) {
+ $messages[ $function_name ] = $message;
+ },
+ 10,
+ 2
+ );
$suffix = wp_unique_id();
$category = wp_insert_term( 'Unsupported orderby ' . $suffix, 'product_cat' );
$product = WC_Helper_Product::create_simple_product();
@@ -1749,12 +1758,22 @@ class WC_Product_Functions_Tests extends \WC_Unit_Test_Case {
$expected = get_the_term_list( $product->get_id(), 'product_cat', '', ', ', '' );
$this->setExpectedIncorrectUsage( 'wc_get_product_category_list' );
+ add_filter(
+ 'gettext',
+ function ( $translation, $text, $domain ) {
+ return 'woocommerce' === $domain ? 'Übersetzt: ' . $text : $translation;
+ },
+ 10,
+ 3
+ );
$this->assertSame(
$expected,
wc_get_product_category_list( $product->get_id(), ', ', '', '', 'menu_order' ),
'An unsupported ordering mode should still return the WordPress term-list output.'
);
+ $this->assertArrayHasKey( 'wc_get_product_category_list', $messages, 'An unsupported ordering mode should raise a notice.' );
+ $this->assertStringStartsWith( 'Unsupported $orderby value "menu_order". Use "name", "breadcrumb", or an empty string for WordPress term-list order.', $messages['wc_get_product_category_list'], 'The notice should be the English message.' );
} finally {
WC_Helper_Product::delete_product( $product->get_id() );
wp_delete_term( $category['term_id'], 'product_cat' );
diff --git a/plugins/woocommerce/tests/php/src/Admin/Settings/SettingsSectionRegistryTest.php b/plugins/woocommerce/tests/php/src/Admin/Settings/SettingsSectionRegistryTest.php
index cd41d3d3131..f42f21bcf4e 100644
--- a/plugins/woocommerce/tests/php/src/Admin/Settings/SettingsSectionRegistryTest.php
+++ b/plugins/woocommerce/tests/php/src/Admin/Settings/SettingsSectionRegistryTest.php
@@ -1073,4 +1073,37 @@ class SettingsSectionRegistryTest extends WC_Unit_Test_Case {
return $previous_settings;
}
+
+ /**
+ * @testdox Should report a gateway collision in English, whatever the site language.
+ */
+ public function test_gateway_collision_notice_is_not_translated(): void {
+ $this->setExpectedIncorrectUsage( SettingsSectionRegistry::class . '::register' );
+ add_filter(
+ 'gettext',
+ function ( $translation, $text, $domain ) {
+ return 'woocommerce' === $domain ? 'Übersetzt: ' . $text : $translation;
+ },
+ 10,
+ 3
+ );
+ $messages = array();
+ add_action(
+ 'doing_it_wrong_run',
+ function ( $function_name, $message ) use ( &$messages ) {
+ $messages[ $function_name ] = $message;
+ },
+ 10,
+ 2
+ );
+
+ SettingsSectionRegistry::get_instance()->register( $this->get_registered_section( 'bacs' ) );
+
+ $this->assertArrayHasKey( SettingsSectionRegistry::class . '::register', $messages, 'The collision should raise a notice.' );
+ $this->assertStringStartsWith(
+ 'The settings section "checkout/bacs" conflicts with an existing payment gateway section.',
+ $messages[ SettingsSectionRegistry::class . '::register' ],
+ 'The notice should be the escaped English message.'
+ );
+ }
}
diff --git a/plugins/woocommerce/tests/php/src/Internal/Admin/Settings/SettingsUIFeatureFlagTest.php b/plugins/woocommerce/tests/php/src/Internal/Admin/Settings/SettingsUIFeatureFlagTest.php
index 1705934e9e8..7ce9b6d8351 100644
--- a/plugins/woocommerce/tests/php/src/Internal/Admin/Settings/SettingsUIFeatureFlagTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/Admin/Settings/SettingsUIFeatureFlagTest.php
@@ -1792,4 +1792,25 @@ class SettingsUIFeatureFlagTest extends WC_Unit_Test_Case {
remove_action( 'woocommerce_settings_' . $current_tab, $action );
}
}
+
+ /**
+ * @testdox Should keep the script handle failure reason in English, whatever the site language.
+ */
+ public function test_script_handle_failure_reason_is_not_translated(): void {
+ add_filter(
+ 'gettext',
+ function ( $translation, $text, $domain ) {
+ return 'woocommerce' === $domain ? 'Übersetzt: ' . $text : $translation;
+ },
+ 10,
+ 3
+ );
+ $context = SettingsUIRequestContext::for_settings_page( $this->get_settings_ui_test_page_with_script_handles( array( 42 ) ), '' );
+
+ $this->assertSame(
+ 'Settings UI script handles could not be resolved: Settings UI script handles must be non-empty strings.',
+ $context->get_script_handles_failure_reason(),
+ 'The failure reason feeds a developer notice and should stay in English.'
+ );
+ }
}
diff --git a/plugins/woocommerce/tests/php/src/Internal/Features/FeaturesControllerTest.php b/plugins/woocommerce/tests/php/src/Internal/Features/FeaturesControllerTest.php
index 73ede7e0e8f..85341abc2bf 100644
--- a/plugins/woocommerce/tests/php/src/Internal/Features/FeaturesControllerTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/Features/FeaturesControllerTest.php
@@ -283,7 +283,7 @@ class FeaturesControllerTest extends \WC_Unit_Test_Case {
}
/**
- * @testdox Feature definition initialization is safe when a translation callback checks a feature.
+ * @testdox Feature definition initialization is safe when a translation callback checks a feature, and the notice stays in English.
*/
public function test_feature_definition_initialization_is_reentrant_safe() {
$reflection_class = new \ReflectionClass( $this->sut );
@@ -303,15 +303,13 @@ class FeaturesControllerTest extends \WC_Unit_Test_Case {
$notices = array();
$gettext_filter = function ( $translation, $text, $domain ) use ( &$reentrant_feature_enabled, &$translation_count ) {
- unset( $text, $domain ); // Avoid parameter not used PHPCS errors.
-
++$translation_count;
if ( null === $reentrant_feature_enabled ) {
$reentrant_feature_enabled = $this->sut->feature_is_enabled( 'order_withdrawal' );
}
- return $translation;
+ return 'woocommerce' === $domain ? 'Übersetzt: ' . $text : $translation;
};
$notice_listener = function ( $function_name, $message, $version ) use ( &$notices, $notice_function ) {
if ( $notice_function === $function_name ) {
@@ -335,7 +333,7 @@ class FeaturesControllerTest extends \WC_Unit_Test_Case {
$this->assertFalse( $reentrant_feature_enabled );
$this->assertGreaterThan( 0, $translation_count );
$this->assertCount( 1, $notices );
- $this->assertStringContainsString( 'Use the woocommerce_init action or later.', $notices[0]['message'] );
+ $this->assertStringStartsWith( 'FeaturesController methods that access feature definitions should not be called while feature definitions are being initialized. Use the woocommerce_init action or later.', $notices[0]['message'], 'The reentry notice should be the English message.' );
$this->assertSame( '11.3.0', $notices[0]['version'] );
$this->assertNotNull( $this->sut->get_feature_definition( 'order_withdrawal' ) );
}
@@ -427,9 +425,17 @@ class FeaturesControllerTest extends \WC_Unit_Test_Case {
}
/**
- * @testdox 'declare_compatibility' fails when invoked from outside the 'before_woocommerce_init' action.
+ * @testdox 'declare_compatibility' fails when invoked from outside the 'before_woocommerce_init' action, with an English notice.
*/
public function test_declare_compatibility_outside_before_woocommerce_init_hook() {
+ add_filter(
+ 'gettext',
+ function ( $translation, $text, $domain ) {
+ return 'woocommerce' === $domain ? 'Übersetzt: ' . $text : $translation;
+ },
+ 10,
+ 3
+ );
$function = null;
$message = null;
$version = null;
@@ -571,9 +577,17 @@ class FeaturesControllerTest extends \WC_Unit_Test_Case {
}
/**
- * @testdox 'get_compatible_features_for_plugin' fails when invoked before the 'woocommerce_init' hook.
+ * @testdox 'get_compatible_features_for_plugin' fails when invoked before the 'woocommerce_init' hook, with an English notice.
*/
public function test_get_compatible_features_for_plugin_before_woocommerce_init_hook() {
+ add_filter(
+ 'gettext',
+ function ( $translation, $text, $domain ) {
+ return 'woocommerce' === $domain ? 'Übersetzt: ' . $text : $translation;
+ },
+ 10,
+ 3
+ );
$function = null;
$message = null;
$version = null;