You've already forked wp-prometheus
fix: Defer DashboardProvider translations to avoid early textdomain loading (v0.4.8)
All checks were successful
Create Release Package / build-release (push) Successful in 54s
All checks were successful
Create Release Package / build-release (push) Successful in 54s
DashboardProvider constructor also had __() calls during plugins_loaded. Applied same lazy-initialization pattern as Settings tab labels. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -11,7 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
- Fixed `_load_textdomain_just_in_time` notice on admin pages (WordPress 6.7+ compatibility)
|
- Fixed `_load_textdomain_just_in_time` notice on admin pages (WordPress 6.7+ compatibility)
|
||||||
- Deferred `load_plugin_textdomain()` to `init` action instead of `plugins_loaded`
|
- Deferred `load_plugin_textdomain()` to `init` action instead of `plugins_loaded`
|
||||||
- Deferred Settings tab label initialization to avoid early translation loading
|
- Deferred Settings tab label and DashboardProvider initialization to avoid early translation loading
|
||||||
|
|
||||||
## [0.4.7] - 2026-02-03
|
## [0.4.7] - 2026-02-03
|
||||||
|
|
||||||
|
|||||||
@@ -295,9 +295,10 @@ add_action( 'wp_prometheus_collect_metrics', function( $collector ) {
|
|||||||
- Fixed `_load_textdomain_just_in_time` warning on admin pages (WordPress 6.7+ compatibility)
|
- Fixed `_load_textdomain_just_in_time` warning on admin pages (WordPress 6.7+ compatibility)
|
||||||
- Root cause: `load_plugin_textdomain()` was called during `plugins_loaded` in `Plugin::__construct()`
|
- Root cause: `load_plugin_textdomain()` was called during `plugins_loaded` in `Plugin::__construct()`
|
||||||
- WordPress 6.7+ requires textdomain loading at the `init` action or later
|
- WordPress 6.7+ requires textdomain loading at the `init` action or later
|
||||||
- Two changes made:
|
- Three classes needed fixing:
|
||||||
- `Plugin.php`: Deferred `load_textdomain()` to `init` action hook, changed method visibility to public
|
- `Plugin.php`: Deferred `load_textdomain()` to `init` action hook, changed method visibility to public
|
||||||
- `Settings.php`: Deferred tab label initialization (which uses `__()`) to a lazy `get_tabs()` method
|
- `Settings.php`: Deferred tab label initialization (which uses `__()`) to a lazy `get_tabs()` method
|
||||||
|
- `DashboardProvider.php`: Deferred built-in dashboard definitions (with `__()` calls) to a lazy `get_builtin_dashboards()` method
|
||||||
- Cleared Known Bugs section — no remaining known issues
|
- Cleared Known Bugs section — no remaining known issues
|
||||||
- **Key Learning**: WordPress 6.7 textdomain loading requirements
|
- **Key Learning**: WordPress 6.7 textdomain loading requirements
|
||||||
- `load_plugin_textdomain()` must be called at `init` or later
|
- `load_plugin_textdomain()` must be called at `init` or later
|
||||||
|
|||||||
@@ -53,30 +53,43 @@ class DashboardProvider {
|
|||||||
*/
|
*/
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
$this->dashboard_dir = WP_PROMETHEUS_PATH . 'assets/dashboards/';
|
$this->dashboard_dir = WP_PROMETHEUS_PATH . 'assets/dashboards/';
|
||||||
|
}
|
||||||
|
|
||||||
$this->builtin_dashboards = array(
|
/**
|
||||||
'wordpress-overview' => array(
|
* Get built-in dashboard definitions.
|
||||||
'title' => __( 'WordPress Overview', 'wp-prometheus' ),
|
*
|
||||||
'description' => __( 'General WordPress metrics including users, posts, comments, and plugins.', 'wp-prometheus' ),
|
* Lazily initializes dashboard labels to avoid triggering textdomain loading
|
||||||
'file' => 'wordpress-overview.json',
|
* before the 'init' action (required since WordPress 6.7).
|
||||||
'icon' => 'dashicons-wordpress',
|
*
|
||||||
'source' => 'builtin',
|
* @return array
|
||||||
),
|
*/
|
||||||
'wordpress-runtime' => array(
|
private function get_builtin_dashboards(): array {
|
||||||
'title' => __( 'Runtime Performance', 'wp-prometheus' ),
|
if ( empty( $this->builtin_dashboards ) ) {
|
||||||
'description' => __( 'HTTP request metrics, database query performance, and response times.', 'wp-prometheus' ),
|
$this->builtin_dashboards = array(
|
||||||
'file' => 'wordpress-runtime.json',
|
'wordpress-overview' => array(
|
||||||
'icon' => 'dashicons-performance',
|
'title' => __( 'WordPress Overview', 'wp-prometheus' ),
|
||||||
'source' => 'builtin',
|
'description' => __( 'General WordPress metrics including users, posts, comments, and plugins.', 'wp-prometheus' ),
|
||||||
),
|
'file' => 'wordpress-overview.json',
|
||||||
'wordpress-woocommerce' => array(
|
'icon' => 'dashicons-wordpress',
|
||||||
'title' => __( 'WooCommerce Store', 'wp-prometheus' ),
|
'source' => 'builtin',
|
||||||
'description' => __( 'WooCommerce metrics including products, orders, revenue, and customers.', 'wp-prometheus' ),
|
),
|
||||||
'file' => 'wordpress-woocommerce.json',
|
'wordpress-runtime' => array(
|
||||||
'icon' => 'dashicons-cart',
|
'title' => __( 'Runtime Performance', 'wp-prometheus' ),
|
||||||
'source' => 'builtin',
|
'description' => __( 'HTTP request metrics, database query performance, and response times.', 'wp-prometheus' ),
|
||||||
),
|
'file' => 'wordpress-runtime.json',
|
||||||
);
|
'icon' => 'dashicons-performance',
|
||||||
|
'source' => 'builtin',
|
||||||
|
),
|
||||||
|
'wordpress-woocommerce' => array(
|
||||||
|
'title' => __( 'WooCommerce Store', 'wp-prometheus' ),
|
||||||
|
'description' => __( 'WooCommerce metrics including products, orders, revenue, and customers.', 'wp-prometheus' ),
|
||||||
|
'file' => 'wordpress-woocommerce.json',
|
||||||
|
'icon' => 'dashicons-cart',
|
||||||
|
'source' => 'builtin',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return $this->builtin_dashboards;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -106,7 +119,7 @@ class DashboardProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check for duplicate slugs (built-in takes precedence).
|
// Check for duplicate slugs (built-in takes precedence).
|
||||||
if ( isset( $this->builtin_dashboards[ $slug ] ) ) {
|
if ( isset( $this->get_builtin_dashboards()[ $slug ] ) ) {
|
||||||
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
|
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
|
||||||
// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
|
// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
|
||||||
error_log( "WP Prometheus: Dashboard slug '$slug' conflicts with built-in dashboard" );
|
error_log( "WP Prometheus: Dashboard slug '$slug' conflicts with built-in dashboard" );
|
||||||
@@ -273,7 +286,7 @@ class DashboardProvider {
|
|||||||
$available = array();
|
$available = array();
|
||||||
|
|
||||||
// Add built-in dashboards (check file exists).
|
// Add built-in dashboards (check file exists).
|
||||||
foreach ( $this->builtin_dashboards as $slug => $dashboard ) {
|
foreach ( $this->get_builtin_dashboards() as $slug => $dashboard ) {
|
||||||
$file_path = $this->dashboard_dir . $dashboard['file'];
|
$file_path = $this->dashboard_dir . $dashboard['file'];
|
||||||
if ( file_exists( $file_path ) ) {
|
if ( file_exists( $file_path ) ) {
|
||||||
$available[ $slug ] = $dashboard;
|
$available[ $slug ] = $dashboard;
|
||||||
@@ -306,8 +319,9 @@ class DashboardProvider {
|
|||||||
$slug = sanitize_file_name( $slug );
|
$slug = sanitize_file_name( $slug );
|
||||||
|
|
||||||
// Check built-in dashboards first.
|
// Check built-in dashboards first.
|
||||||
if ( isset( $this->builtin_dashboards[ $slug ] ) ) {
|
$builtin = $this->get_builtin_dashboards();
|
||||||
$dashboard = $this->builtin_dashboards[ $slug ];
|
if ( isset( $builtin[ $slug ] ) ) {
|
||||||
|
$dashboard = $builtin[ $slug ];
|
||||||
$file_path = $this->dashboard_dir . $dashboard['file'];
|
$file_path = $this->dashboard_dir . $dashboard['file'];
|
||||||
|
|
||||||
// Security: Ensure file is within dashboard directory.
|
// Security: Ensure file is within dashboard directory.
|
||||||
@@ -377,8 +391,9 @@ class DashboardProvider {
|
|||||||
|
|
||||||
$slug = sanitize_file_name( $slug );
|
$slug = sanitize_file_name( $slug );
|
||||||
|
|
||||||
if ( isset( $this->builtin_dashboards[ $slug ] ) ) {
|
$builtin = $this->get_builtin_dashboards();
|
||||||
return $this->builtin_dashboards[ $slug ];
|
if ( isset( $builtin[ $slug ] ) ) {
|
||||||
|
return $builtin[ $slug ];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( isset( $this->registered_dashboards[ $slug ] ) ) {
|
if ( isset( $this->registered_dashboards[ $slug ] ) ) {
|
||||||
@@ -401,8 +416,9 @@ class DashboardProvider {
|
|||||||
$slug = sanitize_file_name( $slug );
|
$slug = sanitize_file_name( $slug );
|
||||||
|
|
||||||
// Built-in dashboards have predefined filenames.
|
// Built-in dashboards have predefined filenames.
|
||||||
if ( isset( $this->builtin_dashboards[ $slug ] ) ) {
|
$builtin = $this->get_builtin_dashboards();
|
||||||
return $this->builtin_dashboards[ $slug ]['file'];
|
if ( isset( $builtin[ $slug ] ) ) {
|
||||||
|
return $builtin[ $slug ]['file'];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Registered dashboards - use file basename or generate from slug.
|
// Registered dashboards - use file basename or generate from slug.
|
||||||
|
|||||||
Reference in New Issue
Block a user