diff --git a/CHANGELOG.md b/CHANGELOG.md index 809d29f..e47b91d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,8 @@ Versioning: [Semantic Versioning](https://semver.org/). ## [2.5.1] - 2026-06-17 ### Fixed -- PHP 8.3 `TypeError` on Articles admin page: `number_format()` rejects the numeric string returned by `$wpdb->get_var()`. Cast `$total` to `(int)` at point of assignment in `admin/partials/articles-list.php` (#31). +- PHP 8.3 `TypeError` on Articles admin page: `number_format()` rejects the numeric string returned by `$wpdb->get_var()`. Cast `$total` to `(int)` at point of assignment in `admin/partials/articles-list.php` (#32). +- PHP 8.3 `TypeError` on Analytics Dashboard page: `number_format()` rejects SUM aggregate strings returned by `$wpdb->get_results()`. Cast `$article->total_clicks` and `$article->total_unique` to `(int)` inline in `admin/partials/dashboard.php` (same-class fix, no PR number — follow-on to #32). ## [2.5.0] — 2026-06-16 diff --git a/admin/partials/dashboard.php b/admin/partials/dashboard.php index c79f5ad..395cc2f 100755 --- a/admin/partials/dashboard.php +++ b/admin/partials/dashboard.php @@ -105,8 +105,8 @@ $total_articles = count( $top_articles ); title ); ?> source ); ?> categories ); ?> - total_clicks ) ); ?> - total_unique ) ); ?> + total_clicks ) ); ?> + total_unique ) ); ?> diff --git a/tests/unit/DashboardTopArticlesCastTest.php b/tests/unit/DashboardTopArticlesCastTest.php new file mode 100644 index 0000000..10ff37f --- /dev/null +++ b/tests/unit/DashboardTopArticlesCastTest.php @@ -0,0 +1,41 @@ +get_results() do not + * cause a TypeError in number_format() (PHP 8.3 strict typing). + * Mirrors the fix in admin/partials/dashboard.php lines 108-109. + */ + public function test_total_clicks_cast_prevents_type_error() { + $article = (object) array( + 'total_clicks' => '1234', // numeric string from $wpdb->get_results() + 'total_unique' => '987', + ); + // Simulate the inline cast applied in dashboard.php + $formatted_clicks = number_format( (int) $article->total_clicks ); + $formatted_unique = number_format( (int) $article->total_unique ); + $this->assertSame( '1,234', $formatted_clicks ); + $this->assertSame( '987', $formatted_unique ); + } + + /** + * Verify NULL SUM() (no rows) results in 0, not a TypeError. + */ + public function test_null_sum_cast_to_zero() { + $article = (object) array( + 'total_clicks' => null, + 'total_unique' => null, + ); + $formatted_clicks = number_format( (int) $article->total_clicks ); + $formatted_unique = number_format( (int) $article->total_unique ); + $this->assertSame( '0', $formatted_clicks ); + $this->assertSame( '0', $formatted_unique ); + } +}