From 7f588511097a72525f72bc19854fc52f0aa573a9 Mon Sep 17 00:00:00 2001 From: Andy Vandenberghe Date: Sun, 4 Oct 2026 21:58:25 +0200 Subject: [PATCH] Honour the ACP "Show like counts" setting The ACP saved rt_show_likes, but nothing read it: like counts showed whenever Post Love was installed, whatever the setting. Add show_likes() (Post Love present and rt_show_likes on) and use it for the S_POSTLOVE template flag and for fetching the like counts, so switching the setting off also skips the Post Love query. Closes #197 Co-Authored-By: Claude Opus 5.5 --- core/recenttopics.php | 17 ++- tests/core/topic_likes_test.php | 183 ++++++++++++++++++++++++++++++++ tests/tests.md | 18 +++- 3 files changed, 214 insertions(+), 4 deletions(-) create mode 100644 tests/core/topic_likes_test.php diff --git a/core/recenttopics.php b/core/recenttopics.php index 74fca51..0d94036 100644 --- a/core/recenttopics.php +++ b/core/recenttopics.php @@ -443,7 +443,7 @@ public function display_recent_topics($tpl_loopname = 'recent_topics', $context 'LAST_POST_IMG' => $this->user->img('icon_topic_latest', 'VIEW_LATEST_POST'), 'POLL_IMG' => $this->user->img('icon_topic_poll', 'TOPIC_POLL'), 'ADS_INDEX_CODE' => $ads_index_code, - 'S_POSTLOVE' => $this->topic_likes_service !== null, + 'S_POSTLOVE' => $this->show_likes(), strtoupper($tpl_loopname) . '_DISPLAY' => true, ); @@ -457,6 +457,17 @@ public function display_recent_topics($tpl_loopname = 'recent_topics', $context $this->fill_template($tpl_loopname, $topic_tracking_info, $topics_count); } + /** + * Whether Post Love like counts are shown: the service must be installed and the ACP + * "Show like counts" setting (rt_show_likes) switched on (issue #197). + * + * @return bool + */ + private function show_likes(): bool + { + return $this->topic_likes_service !== null && !empty($this->config['rt_show_likes']); + } + /** * Narrow the board's forums down to the ones this list may draw topics from. * @@ -775,9 +786,9 @@ private function fill_template($tpl_loopname, $topic_tracking_info, int $topics_ $rowset = $this->get_topics_sql(); $topic_icons = array(); - // Get postlove like counts if installed + // Get postlove like counts if installed and switched on in the ACP $topic_likes = []; - if ($this->topic_likes_service !== null && !empty($this->topic_list)) + if ($this->show_likes() && !empty($this->topic_list)) { $topic_likes = $this->topic_likes_service->get_topic_like_counts($this->topic_list); } diff --git a/tests/core/topic_likes_test.php b/tests/core/topic_likes_test.php new file mode 100644 index 0000000..9d9a3bf --- /dev/null +++ b/tests/core/topic_likes_test.php @@ -0,0 +1,183 @@ +likes_service = new class { + public $calls = 0; + public function get_topic_like_counts(array $topic_ids) + { + $this->calls++; + return [42 => 7]; + } + }; + + $row = [ + 'topic_id' => 42, 'forum_id' => 1, 'topic_type' => POST_NORMAL, 'topic_status' => ITEM_UNLOCKED, + 'topic_moved_id' => 0, 'topic_visibility' => ITEM_APPROVED, 'topic_posts_unapproved' => 0, + 'topic_reported' => 0, 'topic_attachment' => 0, 'topic_last_post_time' => 1700000000, + 'topic_last_view_time' => 1700000000, 'topic_time' => 1699990000, 'topic_last_post_id' => 99, + 'topic_last_post_subject' => 'Test reply', 'topic_title' => 'Test topic', 'topic_views' => 10, + 'icon_id' => 0, 'poll_start' => 0, 'topic_posted' => 0, 'topic_poster' => 2, + 'topic_first_poster_name' => 'testuser', 'topic_first_poster_colour' => '', + 'topic_last_poster_id' => 2, 'topic_last_poster_name' => 'testuser', + 'topic_last_poster_colour' => '', 'forum_name' => 'General', + ]; + $db = $this->createMock(\phpbb\db\driver\driver_interface::class); + $db->method('sql_in_set')->willReturn('1=1'); + $db->method('sql_build_query')->willReturn('SELECT 1'); + $db->method('sql_query_limit')->willReturn('result'); + $db->method('sql_fetchrow')->willReturnOnConsecutiveCalls($row, false); + + $template = $this->createMock(\phpbb\template\template::class); + $template->method('assign_block_vars')->willReturnCallback(function ($loop, $vars) { + $this->assigned = $vars; + }); + + $content_visibility = $this->createMock(\phpbb\content_visibility::class); + $content_visibility->method('get_count')->willReturn(1); + + $user = $this->createMock(\phpbb\user::class); + $user->data = ['user_id' => 2, 'is_registered' => true]; + $user->page = ['query_string' => '', 'page_name' => 'index.php']; + $user->session_id = 'testsession'; + $user->method('format_date')->willReturn('01 Jan 2026'); + $user->method('img')->willReturn(''); + + $dispatcher = new \phpbb\event\dispatcher(); + + $rt = new \avathar\recenttopics\core\recenttopics( + $this->createMock(\phpbb\auth\auth::class), + $this->createMock(\phpbb\cache\service::class), + new \phpbb\config\config(['posts_per_page' => 10, 'rt_topic_link_to' => 0, 'rt_show_likes' => $rt_show_likes]), + $this->createMock(\phpbb\language\language::class), + $content_visibility, + $db, + $dispatcher, + $this->createMock(\phpbb\pagination::class), + $this->createMock(\phpbb\request\request_interface::class), + $template, + $user, + '/', + 'php', + $this->createMock(\phpbb\config\db_text::class), + null, + $this->likes_service + ); + + foreach ([ + 'topic_list' => [42], 'sort_topics' => 'topic_last_post_time', 'display_parent_forums' => false, + 'topics_per_page' => 5, 'unread_only' => false, 'icons' => [], 'rtstart' => 0, 'total_topics_limit' => 100, + ] as $name => $value) + { + $property = new \ReflectionProperty($rt, $name); + $property->setAccessible(true); + $property->setValue($rt, $value); + } + + $GLOBALS['phpbb_dispatcher'] = $dispatcher; + $GLOBALS['config'] = ['allow_smilies' => 0, 'allow_nocensors' => 1]; + $GLOBALS['user'] = $user; + + return $rt; + } + + private function call_private($rt, string $method, array $args = []) + { + $ref = new \ReflectionMethod($rt, $method); + $ref->setAccessible(true); + return $ref->invokeArgs($rt, $args); + } + + /** + * "Show like counts" off: no like counts, and Post Love is not queried (#197). + */ + public function test_like_counts_hidden_when_setting_is_off() + { + $rt = $this->make_rt(0); + + $this->call_private($rt, 'fill_template', ['recent_topics', [], 1]); + + $this->assertSame(0, $this->assigned['TOPIC_LIKES']); + $this->assertSame(0, $this->likes_service->calls); + $this->assertFalse($this->call_private($rt, 'show_likes')); + } + + /** + * "Show like counts" on and Post Love available: the topic's like count is shown. + */ + public function test_like_counts_shown_when_setting_is_on() + { + $rt = $this->make_rt(1); + + $this->call_private($rt, 'fill_template', ['recent_topics', [], 1]); + + $this->assertSame(7, $this->assigned['TOPIC_LIKES']); + $this->assertSame(1, $this->likes_service->calls); + $this->assertTrue($this->call_private($rt, 'show_likes')); + } +} +} diff --git a/tests/tests.md b/tests/tests.md index dc2571f..45a7582 100644 --- a/tests/tests.md +++ b/tests/tests.md @@ -44,6 +44,7 @@ tests/ ├── core/ │ ├── forum_list_test.php Which forums the list may draw topics from │ ├── topic_count_test.php "Show all pages" count uses the forum list +│ ├── topic_likes_test.php ACP "Show like counts" setting │ └── recenttopics_events_test.php Public event API contract (contrib/events.md) └── functional/ └── recenttopics_test.php End-to-end browser tests @@ -190,7 +191,22 @@ It runs `display_recent_topics()` with mocked `auth`, `user`, `db` and `content_ --- -## 7. Functional tests (`functional/recenttopics_test.php`) +## 7. Like counts (`core/topic_likes_test.php`) + +**What this code does:** +With Post Love installed, Recent Topics can show each topic's like count. `show_likes()` decides whether it does: the Post Love service must be present and the ACP "Show like counts" setting (`rt_show_likes`) switched on. It drives both the `S_POSTLOVE` template flag and whether the like counts are fetched at all. + +**What this test file does:** +It runs `fill_template()` for one topic with a stand-in Post Love service that reports 7 likes and counts its calls. (The real service is optional and may not be installed, so it is not mocked by class.) + +| Test | Scenario | What it verifies | +|------|----------|-----------------| +| `test_like_counts_hidden_when_setting_is_off` | `rt_show_likes = 0` | `TOPIC_LIKES` is 0, Post Love is never queried, `show_likes()` is false. Before the fix the setting was ignored (#197) | +| `test_like_counts_shown_when_setting_is_on` | `rt_show_likes = 1` | `TOPIC_LIKES` is 7, Post Love is queried once, `show_likes()` is true | + +--- + +## 8. Functional tests (`functional/recenttopics_test.php`) **What this code does:** These tests start a real phpBB installation (using the test framework's built-in install), enable the extension, and make HTTP requests using a real browser-like crawler (Symfony DomCrawler). They check the actual rendered HTML for specific elements.