From 652b151711f2574b9bc1440b5aa49949b99d7c9b Mon Sep 17 00:00:00 2001 From: Andy Vandenberghe Date: Sun, 4 Oct 2026 23:29:16 +0200 Subject: [PATCH] Show the UCP section to members who only have u_rt_number S_RT_SHOW, the flag that renders the Recent Topics section in UCP > Board preferences, was set for u_rt_enable, u_rt_location, u_rt_sort_start_time and u_rt_unread_only, but not u_rt_number. The number field sits inside that section, so a member granted only "Can change the number of recent topics" saw no section at all. Closes #216 Co-Authored-By: Claude Opus 5.5 --- event/ucp_listener.php | 2 +- tests/event/ucp_listener_test.php | 40 +++++++++++++++++++++++++++++++ tests/tests.md | 1 + 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/event/ucp_listener.php b/event/ucp_listener.php index 603687e..07f4ec9 100644 --- a/event/ucp_listener.php +++ b/event/ucp_listener.php @@ -154,7 +154,7 @@ public function ucp_prefs_get_data($event) $template_vars = array(); // if authorised for one of these then set ucp master template variable to true - if ($this->auth->acl_get('u_rt_enable') || $this->auth->acl_get('u_rt_location') || $this->auth->acl_get('u_rt_sort_start_time') || $this->auth->acl_get('u_rt_unread_only')) + if ($this->auth->acl_get('u_rt_enable') || $this->auth->acl_get('u_rt_location') || $this->auth->acl_get('u_rt_number') || $this->auth->acl_get('u_rt_sort_start_time') || $this->auth->acl_get('u_rt_unread_only')) { $template_vars += array( 'S_RT_SHOW' => true, diff --git a/tests/event/ucp_listener_test.php b/tests/event/ucp_listener_test.php index 63580d8..92aaba1 100644 --- a/tests/event/ucp_listener_test.php +++ b/tests/event/ucp_listener_test.php @@ -195,6 +195,46 @@ public function test_ucp_prefs_set_data_no_permissions() 'No RT column may be written without the matching permission'); } + /** + * A member holding only u_rt_number (besides u_rt_view) must get the UCP section and its + * number field. S_RT_SHOW left u_rt_number out, so the whole section stayed hidden (#216). + */ + public function test_number_only_permission_shows_ucp_section() + { + $this->user->data = array( + 'user_rt_enable' => 1, + 'user_rt_location' => 'RT_TOP', + 'user_rt_viewforum_location' => 'RT_TOP', + 'user_rt_number' => 5, + 'user_rt_sort_start_time' => 0, + 'user_rt_unread_only' => 0, + ); + + $this->request->method('variable') + ->willReturnCallback(function ($var, $default) { + return $default; + }); + + $this->auth->method('acl_get') + ->willReturnCallback(function ($perm) { + return ($perm === 'u_rt_view' || $perm === 'u_rt_number'); + }); + + $assigned = array(); + $this->template->method('assign_vars') + ->willReturnCallback(function ($vars) use (&$assigned) { + $assigned = array_merge($assigned, $vars); + }); + + $this->set_listener(); + + $event = new \phpbb\event\data(array('data' => array(), 'submit' => false)); + $this->listener->ucp_prefs_get_data($event); + + $this->assertTrue(!empty($assigned['S_RT_SHOW']), 'S_RT_SHOW must be set so the UCP section renders'); + $this->assertTrue(!empty($assigned['A_RT_NUMBER']), 'The number field must be offered'); + } + public function test_ucp_prefs_get_data_no_submit() { $this->user->data = array( diff --git a/tests/tests.md b/tests/tests.md index d5edf9a..d093cff 100644 --- a/tests/tests.md +++ b/tests/tests.md @@ -106,6 +106,7 @@ Creates the listener with mocks for auth, config, request, template, user, langu |------|----------|--------------------| | `test_getSubscribedEvents` | Verifies the 3 expected event subscriptions | Accidentally removed subscription stops the UCP page from working | | `test_ucp_prefs_set_data` | Submits 5 preference fields | Each `data['rt_*']` field must map to the correct `sql_ary['user_rt_*']` column; a mismatch means preferences silently fail to save | +| `test_number_only_permission_shows_ucp_section` | Page load; user holds only `u_rt_view` and `u_rt_number` | `S_RT_SHOW` and `A_RT_NUMBER` are assigned. `S_RT_SHOW` used to omit `u_rt_number`, hiding the whole section from such a user (#216) | | `test_ucp_prefs_get_data_no_submit` | Page load (submit = false) | Must: merge user DB values into `data`, call `add_lang()`, call `template->assign_vars()` | | `test_submitted_preferences_are_validated` | Data provider: valid values; unknown location; `RT_SIDE` as viewforum location; numbers 100000, 0 and -5 | Locations outside the allowed options fall back to the user's stored value; the number is clamped to 1–999 (#198) | | `test_invalid_stored_location_falls_back_to_board_default` | Submitted and stored locations both invalid | The board default `rt_location` is used (#198) |