From b0c755aeec3ecdb26fe56856815b8de50cd33bbc Mon Sep 17 00:00:00 2001 From: LukeWCS Date: Sat, 4 Apr 2026 19:04:30 +0200 Subject: [PATCH 1/7] 1.2.0-b1 - Interface adjustments and optimization for Toggle Control 1.3 * Updated the `switch()` macro to the version of TC 1.3. * Optimized the Twig code in the ACP module based on TC 1.3. * Optimized the Twig code for the UCP module. This involved removing the generation and deletion of `TOGGLECTRL_RTNG` from the PHP files. --- imcger/recenttopicsng/adm/style/acp_rtng.html | 11 +++++------ imcger/recenttopicsng/composer.json | 4 ++-- imcger/recenttopicsng/controller/admin_controller.php | 1 - .../recenttopicsng/controller/controller_common.php | 3 +-- .../styles/all/template/rtng_macros.html | 3 ++- .../styles/all/template/rtng_user_settings.html | 2 +- 6 files changed, 11 insertions(+), 13 deletions(-) diff --git a/imcger/recenttopicsng/adm/style/acp_rtng.html b/imcger/recenttopicsng/adm/style/acp_rtng.html index e825ecb..9ab070f 100644 --- a/imcger/recenttopicsng/adm/style/acp_rtng.html +++ b/imcger/recenttopicsng/adm/style/acp_rtng.html @@ -11,7 +11,6 @@ #} {% import '@imcger_recenttopicsng/rtng_macros.html' as common %} -{% set switch_type = TOGGLECTRL_TYPE ?? 'toggle' %} {% include 'overall_header.html' %} @@ -29,7 +28,7 @@

{{ lang('RTNG_TITLE') }}

{{ lang('RTNG_ALL_TOPICS_EXP') }}
- {{ common.switch('rtng_all_topics', RTNG_ALL_TOPICS, switch_type) }} + {{ common.switch('rtng_all_topics', RTNG_ALL_TOPICS) }}
@@ -56,7 +55,7 @@

{{ lang('RTNG_TITLE') }}

{{ lang('RTNG_PARENTS_EXP') }}
- {{ common.switch('rtng_parents', RTNG_PARENTS, switch_type) }} + {{ common.switch('rtng_parents', RTNG_PARENTS) }}
@@ -90,10 +89,10 @@

{{ lang('RTNG_TITLE') }}

{{ lang('RTNG_OVERRIDABLE') }}

{{ lang('RTNG_OVERRIDABLE_EXPLAIN', U_SERVER_LOAD) }}

- +
- {% include '@imcger_recenttopicsng/rtng_user_settings.html' %} + {% include '@imcger_recenttopicsng/rtng_user_settings.html' with {'switch_type': TOGGLECTRL_TYPE ?? 'toggle'} %}
@@ -103,7 +102,7 @@

{{ lang('RTNG_TITLE') }}

{{ lang('RTNG_RESET_DEFAULT_EXP') }}
- {{ common.switch('rtng_reset_default', false, switch_type) }} + {{ common.switch('rtng_reset_default', false) }} {{ _self.confirmbox('rtng_reset_default', lang('RTNG_RESET_ASK_BEFORE_EXP')) }}
diff --git a/imcger/recenttopicsng/composer.json b/imcger/recenttopicsng/composer.json index 966d565..82bcacf 100644 --- a/imcger/recenttopicsng/composer.json +++ b/imcger/recenttopicsng/composer.json @@ -3,8 +3,8 @@ "type": "phpbb-extension", "description": "Adds a list with a number of recent topics to the board index.", "homepage": "https://github.com/IMC-GER/RecentTopicsNG", - "version": "1.1.0", - "time": "2026-03-08", + "version": "1.2.0-b1", + "time": "2026-04-04", "license": "GPL-2.0-only", "authors": [ { diff --git a/imcger/recenttopicsng/controller/admin_controller.php b/imcger/recenttopicsng/controller/admin_controller.php index 2355cde..cdeeff4 100644 --- a/imcger/recenttopicsng/controller/admin_controller.php +++ b/imcger/recenttopicsng/controller/admin_controller.php @@ -106,7 +106,6 @@ protected function set_template_vars(): void // Read guest account settings as default and setting template vars $user_data = $this->ctrl_common->get_rtng_user_data(ANONYMOUS); $template_vars = $this->ctrl_common->get_user_set_template_vars(ANONYMOUS, $user_data); - unset($template_vars['TOGGLECTRL_RTNG']); $this->template->assign_vars($template_vars); } diff --git a/imcger/recenttopicsng/controller/controller_common.php b/imcger/recenttopicsng/controller/controller_common.php index eaaf971..b52477f 100644 --- a/imcger/recenttopicsng/controller/controller_common.php +++ b/imcger/recenttopicsng/controller/controller_common.php @@ -143,8 +143,7 @@ public function get_user_set_template_vars(int $user_id, array $template_setting if (count($template_vars)) { - $template_vars['S_RTNG_SHOW'] = true; - $template_vars['TOGGLECTRL_RTNG'] = 'radio'; + $template_vars['S_RTNG_SHOW'] = true; } unset($user_auth); diff --git a/imcger/recenttopicsng/styles/all/template/rtng_macros.html b/imcger/recenttopicsng/styles/all/template/rtng_macros.html index ba6677b..59fbdc6 100644 --- a/imcger/recenttopicsng/styles/all/template/rtng_macros.html +++ b/imcger/recenttopicsng/styles/all/template/rtng_macros.html @@ -10,7 +10,8 @@ * Based on the original NV Recent Topics by Joas Schilling (nickvergessen) #} -{% macro switch(name, checked = false, type = 'toggle') -%} +{% macro switch(name, checked = false, type = null) -%} + {% set type = type ?? TOGGLECTRL_TYPE ?? 'toggle' -%} {% if type == 'toggle' || type == 'checkbox' -%} {%- elseif type == 'radio' -%} diff --git a/imcger/recenttopicsng/styles/all/template/rtng_user_settings.html b/imcger/recenttopicsng/styles/all/template/rtng_user_settings.html index 1706d6a..b0c549d 100644 --- a/imcger/recenttopicsng/styles/all/template/rtng_user_settings.html +++ b/imcger/recenttopicsng/styles/all/template/rtng_user_settings.html @@ -11,7 +11,7 @@ #} {%- import '@imcger_recenttopicsng/rtng_macros.html' as common %} -{%- set switch_type = TOGGLECTRL_RTNG ?? TOGGLECTRL_TYPE ?? 'toggle' %} +{%- set switch_type = switch_type ?? 'radio' %} {%- if RTNG_ENABLE is defined %}
From 90c1aa20ea97aea487e65102613794c95ffbe221 Mon Sep 17 00:00:00 2001 From: Thorsten <88725484+IMC-GER@users.noreply.github.com> Date: Sat, 4 Apr 2026 19:38:23 +0200 Subject: [PATCH 2/7] 1.2.0-b2 Improve events in `rtng_functions.php` * Improve the code for the pagination URL parameters. * Events updated in `fill_template()`, like in `viewforum.php` * Added vars in event `modify_tpl_ary`. `$s_type_switch` and `$s_type_switch_test`. * Added event `topic_row_after`. * Template vars for topic parents moved into `$tpl_ary`. * The `Events.md` file has been updated --- imcger/recenttopicsng/composer.json | 2 +- imcger/recenttopicsng/core/rtng_functions.php | 91 ++++++++++++------- imcger/recenttopicsng/docs/CHANGELOG.md | 11 ++- imcger/recenttopicsng/docs/Events.md | 53 ++++++++--- 4 files changed, 108 insertions(+), 49 deletions(-) diff --git a/imcger/recenttopicsng/composer.json b/imcger/recenttopicsng/composer.json index 82bcacf..1e3c4c4 100644 --- a/imcger/recenttopicsng/composer.json +++ b/imcger/recenttopicsng/composer.json @@ -3,7 +3,7 @@ "type": "phpbb-extension", "description": "Adds a list with a number of recent topics to the board index.", "homepage": "https://github.com/IMC-GER/RecentTopicsNG", - "version": "1.2.0-b1", + "version": "1.2.0-b2", "time": "2026-04-04", "license": "GPL-2.0-only", "authors": [ diff --git a/imcger/recenttopicsng/core/rtng_functions.php b/imcger/recenttopicsng/core/rtng_functions.php index ec0d459..73e0d87 100644 --- a/imcger/recenttopicsng/core/rtng_functions.php +++ b/imcger/recenttopicsng/core/rtng_functions.php @@ -455,6 +455,7 @@ private function fill_template(array $icons, string $tpl_loopname, array $topic_ $vars = ['topic_list', 'rowset']; extract($this->dispatcher->trigger_event('imcger.recenttopicsng.modify_topics_list', compact($vars))); + $s_type_switch = 0; foreach ($rowset as $row) { $first_unread = []; @@ -535,7 +536,6 @@ private function fill_template(array $icons, string $tpl_loopname, array $topic_ $topic_unapproved = ($row['topic_visibility'] == ITEM_UNAPPROVED && $this->auth->acl_get('m_approve', $forum_id)); $posts_unapproved = ($row['topic_visibility'] == ITEM_APPROVED && $row['topic_posts_unapproved'] && $this->auth->acl_get('m_approve', $forum_id)); $u_mcp_queue = ($topic_unapproved || $posts_unapproved) ? append_sid("{$this->root_path}mcp.$this->phpEx", 'i=queue&mode=' . ($topic_unapproved ? 'approve_details' : 'unapproved_posts') . "&t=$topic_id", true, $this->user->session_id) : ''; - $s_type_switch = ($row['topic_type'] == POST_ANNOUNCE || $row['topic_type'] == POST_GLOBAL) ? 1 : 0; if (!empty($icons[$row['icon_id']])) { @@ -553,9 +553,23 @@ private function fill_template(array $icons, string $tpl_loopname, array $topic_ list($topic_author, $topic_author_color, $topic_author_full, $u_topic_author, $last_post_author, $last_post_author_colour, $last_post_author_full, $u_last_post_author) = $this->getusernamestrings($row); + if ($this->config['rtng_parents']) + { + $forum_parents = get_forum_parents($row); + foreach ($forum_parents as $parent_id => $data) + { + $parent_forums[] = [ + 'FORUM_ID' => $parent_id, + 'FORUM_NAME' => $data[0], + 'U_VIEW_FORUM' => append_sid("{$this->root_path}viewforum.{$this->phpEx}", 'f=' . $parent_id), + ]; + } + } + //load language $this->language->add_lang('rtng_common', 'imcger/recenttopicsng'); $tpl_ary = [ + 'parent_forums' => $parent_forums, 'FORUM_ID' => $forum_id, 'TOPIC_ID' => $topic_id, 'TOPIC_AUTHOR' => $topic_author, @@ -621,54 +635,61 @@ private function fill_template(array $icons, string $tpl_loopname, array $topic_ * @var string disp_topic_title Post in Topic title. first, last or first unread post * @var array row Array with topic data * @var array tpl_ary Template block array with topic data + * @var bool s_type_switch Flag indicating if the topic type is [global] announcement + * @var bool s_type_switch_test Flag indicating if the test topic type is [global] announcement * @since 1.0.0 * @changed 1.1.0 Variables added. $disp_topic_title and properties of the first unread post in $row + * @changed 1.2.0 Variables added. s_type_switch and s_type_switch_test */ - $vars = ['disp_topic_title', 'row', 'tpl_ary']; + $vars = [ + 'disp_topic_title', + 'row', + 'tpl_ary', + 's_type_switch', + 's_type_switch_test' + ]; extract($this->dispatcher->trigger_event('imcger.recenttopicsng.modify_tpl_ary', compact($vars))); $this->template->assign_block_vars($tpl_loopname, $tpl_ary); + $this->pagination->generate_template_pagination($view_topic_url, $tpl_loopname . '.pagination', 'start', $replies + 1, $this->config['posts_per_page'], 1, true, true); - if ($this->config['rtng_parents']) - { - $forum_parents = get_forum_parents($row); - foreach ($forum_parents as $parent_id => $data) - { - $this->template->assign_block_vars( - $tpl_loopname . '.parent_forums', [ - 'FORUM_ID' => $parent_id, - 'FORUM_NAME' => $data[0], - 'U_VIEW_FORUM' => append_sid("{$this->root_path}viewforum.$this->phpEx", 'f=' . $parent_id), - ] - ); - } - } + // $s_type_switch = ($row['topic_type'] == POST_ANNOUNCE || $row['topic_type'] == POST_GLOBAL) ? 1 : 0; + + /** + * Event after the recent topic data has been assigned to the template + * + * @event imcger.recenttopicsng.topic_row_after + * @var array row Array with the topic data + * @var array rowset Array with topics data + * @var bool s_type_switch Flag indicating if the topic type is [global] announcement + * @var int topic_id The topic ID + * @var array topic_list Array with current recent topics page topic ids + * @var array tpl_ary Template array with topic data + * @since 1.2.0 + */ + $vars = [ + 'row', + 'rowset', + 's_type_switch', + 'topic_id', + 'topic_list', + 'tpl_ary', + ]; + extract($this->dispatcher->trigger_event('imcger.recenttopicsng.topic_row_after', compact($vars))); + } // end rowsset // Get URL-parameters for pagination - $url_params = explode('&', $this->user->page['query_string']); - $append_params = []; + parse_str($this->user->page['query_string'], $append_params); + unset($append_params[$tpl_loopname . '_start']); - foreach ($url_params as $param) + // Fix MSSTI Advanced BBCode MOD + foreach ($append_params as $key => $value) { - if (!$param) - { - continue; - } - - if (strpos($param, '=') === false) - { - // Fix MSSTI Advanced BBCode MOD - $append_params[$param] = '1'; - continue; - } - - list($name, $value) = explode('=', $param); - - if ($name != $tpl_loopname . '_start') + if ($value === "" || $value === null) { - $append_params[$name] = $value; + $append_params[$key] = "1"; } } diff --git a/imcger/recenttopicsng/docs/CHANGELOG.md b/imcger/recenttopicsng/docs/CHANGELOG.md index 673b753..dae9a67 100644 --- a/imcger/recenttopicsng/docs/CHANGELOG.md +++ b/imcger/recenttopicsng/docs/CHANGELOG.md @@ -1,6 +1,15 @@ -## Changelog Recent Topics NG V1.1.0 +## Changelog Recent Topics NG V1.2.0-b2 This is a non-exhaustive (but still near complete) changelog for Recent Topics NG 1.x including release candidate versions. +#### Changes since V1.1.0 (04/04/2026) + - [Change] Template vars for topic parents moved into `$tpl_ary`. + - [Change] Improve the code for the pagination URL parameters. + - [Chamge] Updated the `switch()` macro to the version of TC 1.3. + - [Change] Optimized the Twig code in the ACP & UCP module based on TC 1.3. + - [Feature] Added vars in event `modify_tpl_ary`. `$s_type_switch` and `$s_type_switch_test`. + - [Feature] Added event `topic_row_after `in `rtng_functions\fill_template`. + + #### Changes since V1.0.1 (08/03/2026) - [Change] Classes have been switched to constructor property promotion. - [Change] Minor changes have been made to the language files. diff --git a/imcger/recenttopicsng/docs/Events.md b/imcger/recenttopicsng/docs/Events.md index b0096d5..0f96702 100644 --- a/imcger/recenttopicsng/docs/Events.md +++ b/imcger/recenttopicsng/docs/Events.md @@ -2,33 +2,62 @@ ## Core Events --- +### `imcger.recenttopicsng.sql_pull_topics_list` +* Description: Event to modify the SQL query before the allowed topics list data is retrieved +* Placement: imcger\recenttopicsng\core\rtng_functions\get_allowed_topics_sql +* Since: 1.0.0 +* known listeners: / +* Arguments: + - @var array sql_array The SQL array + +### `imcger.recenttopicsng.sql_pull_topics_data` +* Description: Event to modify the SQL query before the topics data is retrieved +* Placement: imcger\recenttopicsng\core\rtng_functions\get_topics_sql +* Since: 1.0.0 +* known listeners: + - First & Last avatar (caforum/firstlastavatar) + - Topic Preview (vse/topicpreview) +* Arguments: + - @var array sql_array The SQL array + ### `imcger.recenttopicsng.modify_topics_list` * Description: Event to modify the topics list data before we start the display loop -* Placement: imcger\recenttopicsng\core\rtng_functions\display_recent_topics +* Placement: imcger\recenttopicsng\core\rtng_functions\fill_template * Since: 1.0.0 -* known listeners: / +* known listeners: + - Topic Preview (vse/topicpreview) * Arguments: - @var array topic_list Array of all the topic IDs - @var array rowset The full topics list array ### `imcger.recenttopicsng.modify_tpl_ary` * Description: Modify the topic data before it is assigned to the template -* Placement: imcger\recenttopicsng\core\rtng_functions\display_recent_topics +* Placement: imcger\recenttopicsng\core\rtng_functions\fill_template * Since: 1.0.0 * Changed: 1.1.0 Variables added. $disp_topic_title and properties of the first unread post in $row -* known listeners: / +* @changed 1.2.0 Variables added. s_type_switch and s_type_switch_test +* known listeners: + - First & Last avatar (caforum/firstlastavatar) + - Topic Preview (vse/topicpreview) * Arguments: - @var string disp_topic_title Post in Topic title. first, last or first unread post - - @var array row Array with topic data - - @var array tpl_ary Template block array with topic data - -### `imcger.recenttopicsng.sql_pull_topics_list` -* Description: Event to modify the SQL query before the allowed topics list data is retrieved -* Placement: imcger\recenttopicsng\core\rtng_functions\gettopiclist + - @var array row Array with topic data + - @var array tpl_ary Template block array with topic data + - @var bool s_type_switch Flag indicating if the topic type is [global] announcement + - @var bool s_type_switch_test Flag indicating if the test topic type is [global] announcement + +### `imcger.recenttopicsng.topic_row_after` +* Description: Event after the recent topic data has been assigned to the template +* Placement: imcger\recenttopicsng\core\rtng_functions\fill_template +* @since 1.2.0 * known listeners: / -* Since: 1.0.0 * Arguments: - - @var array sql_array The SQL array + - @var array row Array with the topic data + - @var array rowset Array with topics data + - @var bool s_type_switch Flag indicating if the topic type is [global] announcement + - @var int topic_id The topic ID + - @var array topic_list Array with current recent topics page topic ids + - @var array tpl_ary Template array with topic data --- ## Template Events From 0cc60aa346787ecc0515bc92da704a2e8caec6cc Mon Sep 17 00:00:00 2001 From: Thorsten <88725484+IMC-GER@users.noreply.github.com> Date: Sat, 4 Apr 2026 21:08:23 +0200 Subject: [PATCH 3/7] 1.2.0-b3 Optimized the sql-query for first unread post data. * SQL query string modified to retrieve unread posts data from multiple topics * New function `get_first_unread_post_data()` for db-query *Added new var `topic_unread_post_counter` to `$row` * Updated version number in the language files --- imcger/recenttopicsng/composer.json | 2 +- imcger/recenttopicsng/core/rtng_functions.php | 134 ++++++++++-------- imcger/recenttopicsng/docs/CHANGELOG.md | 5 +- .../language/de/info_acp_rtng.php | 2 +- .../language/de_x_sie/info_acp_rtng.php | 2 +- .../language/en/info_acp_rtng.php | 2 +- 6 files changed, 83 insertions(+), 64 deletions(-) diff --git a/imcger/recenttopicsng/composer.json b/imcger/recenttopicsng/composer.json index 1e3c4c4..e5f09cb 100644 --- a/imcger/recenttopicsng/composer.json +++ b/imcger/recenttopicsng/composer.json @@ -3,7 +3,7 @@ "type": "phpbb-extension", "description": "Adds a list with a number of recent topics to the board index.", "homepage": "https://github.com/IMC-GER/RecentTopicsNG", - "version": "1.2.0-b2", + "version": "1.2.0-b3", "time": "2026-04-04", "license": "GPL-2.0-only", "authors": [ diff --git a/imcger/recenttopicsng/core/rtng_functions.php b/imcger/recenttopicsng/core/rtng_functions.php index 73e0d87..832f3f4 100644 --- a/imcger/recenttopicsng/core/rtng_functions.php +++ b/imcger/recenttopicsng/core/rtng_functions.php @@ -340,7 +340,7 @@ private function get_allowed_topics_sql(array $excluded_topics, int $min_topic_l ], [ 'FROM' => [TOPICS_POSTED_TABLE => 'tp', ], - 'ON' => 'tp.topic_id = t.topic_id AND tp.user_id = ' . (int) $this->user->data['user_id'], + 'ON' => 'tp.topic_id = t.topic_id AND tp.user_id = ' . (int) $this->user->data['user_id'], ], ], 'WHERE' => $this->db->sql_in_set('t.topic_id', $excluded_topics, true) . ' @@ -455,65 +455,36 @@ private function fill_template(array $icons, string $tpl_loopname, array $topic_ $vars = ['topic_list', 'rowset']; extract($this->dispatcher->trigger_event('imcger.recenttopicsng.modify_topics_list', compact($vars))); - $s_type_switch = 0; + // Get author, posttime, id and title of first unread post in topic + $first_unread_post_data = []; + if ($this->user->data['is_registered'] && $this->config['load_db_lastread'] && $this->config['rtng_load_first_unrd_post']) + { + $first_unread_post_data = $this->get_first_unread_post_data($topic_list); + } + + $s_type_switch = false; foreach ($rowset as $row) { - $first_unread = []; $topic_id = $row['topic_id']; $forum_id = $row['forum_id']; $unread_topic = false; $replies = $this->content_visibility->get_count('topic_posts', $row, $forum_id) - 1; - $s_type_switch_test = ($row['topic_type'] == POST_ANNOUNCE || $row['topic_type'] == POST_GLOBAL) ? 1 : 0; + $s_type_switch_test = ($row['topic_type'] == POST_ANNOUNCE || $row['topic_type'] == POST_GLOBAL) ? true : false; $disp_topic_title = $this->user_setting['user_rtng_disp_last_post'] ? 'last_post' : 'first_post'; - if ($this->user->data['is_registered'] && $this->config['load_db_lastread'] && $this->config['rtng_load_first_unrd_post']) + if (isset($first_unread_post_data[$topic_id])) { - // Get author, posttime, id and title of first unread post in topic - $sql_array = [ - 'SELECT' => 'p.poster_id, u.username, u.user_colour, p.post_id, p.post_subject, p.post_time', - 'FROM' => [POSTS_TABLE => 'p', ], - 'LEFT_JOIN' => [ - [ - 'FROM' => [TOPICS_TABLE => 't', ], - 'ON' => "t.topic_id = p.topic_id", - ], - [ - 'FROM' => [TOPICS_TRACK_TABLE => 'tt', ], - 'ON' => "tt.user_id = {$this->user->data['user_id']} - AND tt.topic_id = p.topic_id", - ], - [ - 'FROM' => [FORUMS_TRACK_TABLE => 'ft', ], - 'ON' => "ft.user_id = {$this->user->data['user_id']} - AND ft.forum_id = t.forum_id", - ], - [ - 'FROM' => [USERS_TABLE => 'u', ], - 'ON' => 'u.user_id = p.poster_id', - ], - ], - 'WHERE' => "p.topic_id = $topic_id - AND p.post_time > COALESCE(tt.mark_time, ft.mark_time, {$this->user->data['user_lastmark']}, 0) - AND p.forum_id = $forum_id", - 'ORDER_BY' => 'p.post_time ASC, p.post_id ASC', - ]; - - $sql = $this->db->sql_build_query('SELECT', $sql_array); - $result = $this->db->sql_query_limit($sql, 1); - $first_unread = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - $unread_topic = !empty($first_unread['post_id']); - - if ($this->user_setting['user_rtng_disp_first_unrd_post'] && $unread_topic) + $unread_topic = true; + + if ($this->user_setting['user_rtng_disp_first_unrd_post']) { $disp_topic_title = 'first_unread_post'; - $first_unread_post_author = get_username_string('username', $first_unread['poster_id'], $first_unread['username'], $first_unread['user_colour']); - $first_unread_post_author_color = get_username_string('colour', $first_unread['poster_id'], $first_unread['username'], $first_unread['user_colour']); - $first_unread_post_author_full = get_username_string('full', $first_unread['poster_id'], $first_unread['username'], $first_unread['user_colour']); - $first_unread_post_time = $this->user->format_date($first_unread['post_time']); - $u_first_unread_post_author = get_username_string('profile', $first_unread['poster_id'], $first_unread['username'], $first_unread['user_colour']); + $first_unread_post_author = get_username_string('username', $first_unread_post_data[$topic_id]['poster_id'], $first_unread_post_data[$topic_id]['username'], $first_unread_post_data[$topic_id]['user_colour']); + $first_unread_post_author_color = get_username_string('colour', $first_unread_post_data[$topic_id]['poster_id'], $first_unread_post_data[$topic_id]['username'], $first_unread_post_data[$topic_id]['user_colour']); + $first_unread_post_author_full = get_username_string('full', $first_unread_post_data[$topic_id]['poster_id'], $first_unread_post_data[$topic_id]['username'], $first_unread_post_data[$topic_id]['user_colour']); + $first_unread_post_time = $this->user->format_date($first_unread_post_data[$topic_id]['post_time']); + $u_first_unread_post_author = get_username_string('profile', $first_unread_post_data[$topic_id]['poster_id'], $first_unread_post_data[$topic_id]['username'], $first_unread_post_data[$topic_id]['user_colour']); } } else @@ -521,16 +492,17 @@ private function fill_template(array $icons, string $tpl_loopname, array $topic_ $unread_topic = isset($topic_tracking_info[$forum_id][$row['topic_id']]) && ($row['topic_last_post_time'] > $topic_tracking_info[$forum_id][$row['topic_id']]); } - $row['topic_first_unread_post_id'] = $first_unread['post_id'] ?? ''; - $row['topic_first_unread_poster_id'] = $first_unread['poster_id'] ?? ''; - $row['topic_first_unread_poster_name'] = $first_unread['username'] ?? ''; - $row['topic_first_unread_poster_colour'] = $first_unread['user_colour'] ?? ''; - $row['topic_first_unread_post_subject'] = $first_unread['post_subject'] ?? ''; - $row['topic_first_unread_post_time'] = $first_unread['post_time'] ?? ''; + $row['topic_first_unread_post_id'] = $first_unread_post_data[$topic_id]['post_id'] ?? ''; + $row['topic_first_unread_poster_id'] = $first_unread_post_data[$topic_id]['poster_id'] ?? ''; + $row['topic_first_unread_poster_name'] = $first_unread_post_data[$topic_id]['username'] ?? ''; + $row['topic_first_unread_poster_colour'] = $first_unread_post_data[$topic_id]['user_colour'] ?? ''; + $row['topic_first_unread_post_subject'] = $first_unread_post_data[$topic_id]['post_subject'] ?? ''; + $row['topic_first_unread_post_time'] = $first_unread_post_data[$topic_id]['post_time'] ?? ''; + $row['topic_unread_post_counter'] = $first_unread_post_data[$topic_id]['unread_post_counter'] ?? 0; $view_topic_url = append_sid("{$this->root_path}viewtopic.$this->phpEx", 't=' . $topic_id); $view_last_post_url = append_sid("{$this->root_path}viewtopic.$this->phpEx", 'p=' . $row['topic_last_post_id'] . '#p' . $row['topic_last_post_id']); - $view_first_unread_post_url = !empty($first_unread['post_id']) ? append_sid("{$this->root_path}viewtopic.$this->phpEx", 'p=' . $first_unread['post_id'] . '#p' . $first_unread['post_id']) : ''; + $view_first_unread_post_url = !empty($first_unread_post_data[$topic_id]['post_id']) ? append_sid("{$this->root_path}viewtopic.$this->phpEx", 'p=' . $first_unread_post_data[$topic_id]['post_id'] . '#p' . $first_unread_post_data[$topic_id]['post_id']) : ''; $view_report_url = append_sid("{$this->root_path}mcp.$this->phpEx", 'i=reports&mode=reports&t=' . $topic_id, true, $this->user->session_id); $view_forum_url = append_sid("{$this->root_path}viewforum.$this->phpEx", 'f=' . $forum_id); $topic_unapproved = ($row['topic_visibility'] == ITEM_UNAPPROVED && $this->auth->acl_get('m_approve', $forum_id)); @@ -556,6 +528,7 @@ private function fill_template(array $icons, string $tpl_loopname, array $topic_ if ($this->config['rtng_parents']) { $forum_parents = get_forum_parents($row); + $parent_forums = []; foreach ($forum_parents as $parent_id => $data) { $parent_forums[] = [ @@ -646,7 +619,7 @@ private function fill_template(array $icons, string $tpl_loopname, array $topic_ 'row', 'tpl_ary', 's_type_switch', - 's_type_switch_test' + 's_type_switch_test', ]; extract($this->dispatcher->trigger_event('imcger.recenttopicsng.modify_tpl_ary', compact($vars))); @@ -703,7 +676,54 @@ private function fill_template(array $icons, string $tpl_loopname, array $topic_ } // topics found } - public function validate_start($start, $per_page, $num_items) + public function get_first_unread_post_data(array $topic_list): array + { + // Get author, posttime, id and title of first unread post in topic + $sql_array = [ + 'SELECT' => 'p.topic_id, p.poster_id, u.username, u.user_colour, + p.post_id, p.post_subject, p.post_time, COUNT(p.topic_id) AS unread_post_counter', + 'FROM' => [POSTS_TABLE => 'p', ], + 'LEFT_JOIN' => [ + [ + 'FROM' => [TOPICS_TABLE => 't', ], + 'ON' => "t.topic_id = p.topic_id", + ], + [ + 'FROM' => [TOPICS_TRACK_TABLE => 'tt', ], + 'ON' => "tt.user_id = {$this->user->data['user_id']} + AND tt.topic_id = p.topic_id", + ], + [ + 'FROM' => [FORUMS_TRACK_TABLE => 'ft', ], + 'ON' => "ft.user_id = {$this->user->data['user_id']} + AND ft.forum_id = t.forum_id", + ], + [ + 'FROM' => [USERS_TABLE => 'u', ], + 'ON' => 'u.user_id = p.poster_id', + ], + ], + 'WHERE' => $this->db->sql_in_set('p.topic_id', $topic_list) . " + AND p.post_time > COALESCE(tt.mark_time, ft.mark_time, {$this->user->data['user_lastmark']}, 0)", + 'GROUP_BY' => 'p.topic_id', + 'ORDER_BY' => 'p.post_time ASC, p.post_id ASC', + ]; + + $sql = $this->db->sql_build_query('SELECT', $sql_array); + $result = $this->db->sql_query($sql); + $row_set = $this->db->sql_fetchrowset($result); + $this->db->sql_freeresult($result); + + $first_unread_posts = []; + foreach ($row_set as $row) + { + $first_unread_posts[$row['topic_id']] = $row; + } + + return $first_unread_posts; + } + + public function validate_start(int $start, int $per_page, int $num_items): int { $start = $start >= $num_items ? $num_items - 1 : $start; $start = intdiv($start, $per_page) * $per_page; diff --git a/imcger/recenttopicsng/docs/CHANGELOG.md b/imcger/recenttopicsng/docs/CHANGELOG.md index dae9a67..2157faf 100644 --- a/imcger/recenttopicsng/docs/CHANGELOG.md +++ b/imcger/recenttopicsng/docs/CHANGELOG.md @@ -1,4 +1,4 @@ -## Changelog Recent Topics NG V1.2.0-b2 +## Changelog Recent Topics NG V1.2.0-b3 This is a non-exhaustive (but still near complete) changelog for Recent Topics NG 1.x including release candidate versions. #### Changes since V1.1.0 (04/04/2026) @@ -6,10 +6,10 @@ This is a non-exhaustive (but still near complete) changelog for Recent Topics N - [Change] Improve the code for the pagination URL parameters. - [Chamge] Updated the `switch()` macro to the version of TC 1.3. - [Change] Optimized the Twig code in the ACP & UCP module based on TC 1.3. + - [Change] Optimized the sql-query for first unread post data. - [Feature] Added vars in event `modify_tpl_ary`. `$s_type_switch` and `$s_type_switch_test`. - [Feature] Added event `topic_row_after `in `rtng_functions\fill_template`. - #### Changes since V1.0.1 (08/03/2026) - [Change] Classes have been switched to constructor property promotion. - [Change] Minor changes have been made to the language files. @@ -38,7 +38,6 @@ This is a non-exhaustive (but still near complete) changelog for Recent Topics N - [Fixed] The red fa-file icon is not removed when topics are marked as unread. - [Fixed] Displays locked passworded forums. - #### Changes since V1.0.0 (27/09/2025) - [Change] Removed unnecessary NCO. - [Fixed] Ensured that the correct variable type is always returned. diff --git a/imcger/recenttopicsng/language/de/info_acp_rtng.php b/imcger/recenttopicsng/language/de/info_acp_rtng.php index 7de1a31..3482a75 100644 --- a/imcger/recenttopicsng/language/de/info_acp_rtng.php +++ b/imcger/recenttopicsng/language/de/info_acp_rtng.php @@ -41,7 +41,7 @@ $lang = array_merge($lang, [ // Language pack author 'RTNG_LANG_DESC' => 'Deutsch (Du)', - 'RTNG_LANG_VER' => '1.1.0', + 'RTNG_LANG_VER' => '1.2.0', 'RTNG_LANG_AUTHOR' => 'IMC-GER / LukeWCS', // ACP forums diff --git a/imcger/recenttopicsng/language/de_x_sie/info_acp_rtng.php b/imcger/recenttopicsng/language/de_x_sie/info_acp_rtng.php index 0d61a09..f5b6fe3 100644 --- a/imcger/recenttopicsng/language/de_x_sie/info_acp_rtng.php +++ b/imcger/recenttopicsng/language/de_x_sie/info_acp_rtng.php @@ -41,7 +41,7 @@ $lang = array_merge($lang, [ // Language pack author 'RTNG_LANG_DESC' => 'Deutsch (Sie)', - 'RTNG_LANG_VER' => '1.1.0', + 'RTNG_LANG_VER' => '1.2.0', 'RTNG_LANG_AUTHOR' => 'IMC-GER / LukeWCS', // ACP forums diff --git a/imcger/recenttopicsng/language/en/info_acp_rtng.php b/imcger/recenttopicsng/language/en/info_acp_rtng.php index f1d85dd..be74e8c 100644 --- a/imcger/recenttopicsng/language/en/info_acp_rtng.php +++ b/imcger/recenttopicsng/language/en/info_acp_rtng.php @@ -41,7 +41,7 @@ $lang = array_merge($lang, [ // Language pack author 'RTNG_LANG_DESC' => 'English', - 'RTNG_LANG_VER' => '1.1.0', + 'RTNG_LANG_VER' => '1.2.0', 'RTNG_LANG_AUTHOR' => 'IMC-GER / LukeWCS', // ACP forums From b6682045220a5e897e8eb25e3055d2c05791bebe Mon Sep 17 00:00:00 2001 From: Thorsten <88725484+IMC-GER@users.noreply.github.com> Date: Sun, 5 Apr 2026 13:07:07 +0200 Subject: [PATCH 4/7] 1.2.0-b4 Number of unread posts added to the tooltip * The number of unread posts has been added to the tooltip when the RTNG switch in the Load Settings menu is enabled. --- imcger/recenttopicsng/composer.json | 4 ++-- imcger/recenttopicsng/core/rtng_functions.php | 2 +- imcger/recenttopicsng/docs/CHANGELOG.md | 5 +++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/imcger/recenttopicsng/composer.json b/imcger/recenttopicsng/composer.json index e5f09cb..9f88526 100644 --- a/imcger/recenttopicsng/composer.json +++ b/imcger/recenttopicsng/composer.json @@ -3,8 +3,8 @@ "type": "phpbb-extension", "description": "Adds a list with a number of recent topics to the board index.", "homepage": "https://github.com/IMC-GER/RecentTopicsNG", - "version": "1.2.0-b3", - "time": "2026-04-04", + "version": "1.2.0-b4", + "time": "2026-04-05", "license": "GPL-2.0-only", "authors": [ { diff --git a/imcger/recenttopicsng/core/rtng_functions.php b/imcger/recenttopicsng/core/rtng_functions.php index 832f3f4..eb21bbf 100644 --- a/imcger/recenttopicsng/core/rtng_functions.php +++ b/imcger/recenttopicsng/core/rtng_functions.php @@ -570,7 +570,7 @@ private function fill_template(array $icons, string $tpl_loopname, array $topic_ 'TOPIC_TYPE' => $topic_type, 'TOPIC_IMG_STYLE' => $folder_img, 'TOPIC_FOLDER_IMG' => $this->user->img($folder_img, $folder_alt), - 'TOPIC_FOLDER_IMG_ALT' => $this->language->lang($folder_alt), + 'TOPIC_FOLDER_IMG_ALT' => $row['topic_unread_post_counter'] ? $row['topic_unread_post_counter'] . ' ' . $this->language->lang($folder_alt) : $this->language->lang($folder_alt), 'TOPIC_ICON_IMG' => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['img'] : '', 'TOPIC_ICON_IMG_WIDTH' => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['width'] : '', 'TOPIC_ICON_IMG_HEIGHT' => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['height'] : '', diff --git a/imcger/recenttopicsng/docs/CHANGELOG.md b/imcger/recenttopicsng/docs/CHANGELOG.md index 2157faf..a1896ad 100644 --- a/imcger/recenttopicsng/docs/CHANGELOG.md +++ b/imcger/recenttopicsng/docs/CHANGELOG.md @@ -1,7 +1,7 @@ -## Changelog Recent Topics NG V1.2.0-b3 +## Changelog Recent Topics NG V1.2.0-b4 This is a non-exhaustive (but still near complete) changelog for Recent Topics NG 1.x including release candidate versions. -#### Changes since V1.1.0 (04/04/2026) +#### Changes since V1.1.0 (05/04/2026) - [Change] Template vars for topic parents moved into `$tpl_ary`. - [Change] Improve the code for the pagination URL parameters. - [Chamge] Updated the `switch()` macro to the version of TC 1.3. @@ -9,6 +9,7 @@ This is a non-exhaustive (but still near complete) changelog for Recent Topics N - [Change] Optimized the sql-query for first unread post data. - [Feature] Added vars in event `modify_tpl_ary`. `$s_type_switch` and `$s_type_switch_test`. - [Feature] Added event `topic_row_after `in `rtng_functions\fill_template`. + - [Feature] The number of unread posts has been added to the tooltip when the RTNG switch in the Load Settings menu is enabled. #### Changes since V1.0.1 (08/03/2026) - [Change] Classes have been switched to constructor property promotion. From ab0399d993e0c106cd329030bfb1a538e5cc8808 Mon Sep 17 00:00:00 2001 From: LukeWCS Date: Tue, 7 Apr 2026 23:22:32 +0200 Subject: [PATCH 5/7] 1.2.0-b5 - Fallback for the Twig macro `switch()` --- imcger/recenttopicsng/composer.json | 4 ++-- imcger/recenttopicsng/styles/all/template/rtng_macros.html | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/imcger/recenttopicsng/composer.json b/imcger/recenttopicsng/composer.json index 9f88526..3ab4016 100644 --- a/imcger/recenttopicsng/composer.json +++ b/imcger/recenttopicsng/composer.json @@ -3,8 +3,8 @@ "type": "phpbb-extension", "description": "Adds a list with a number of recent topics to the board index.", "homepage": "https://github.com/IMC-GER/RecentTopicsNG", - "version": "1.2.0-b4", - "time": "2026-04-05", + "version": "1.2.0-b5", + "time": "2026-04-07", "license": "GPL-2.0-only", "authors": [ { diff --git a/imcger/recenttopicsng/styles/all/template/rtng_macros.html b/imcger/recenttopicsng/styles/all/template/rtng_macros.html index 59fbdc6..ca49cb5 100644 --- a/imcger/recenttopicsng/styles/all/template/rtng_macros.html +++ b/imcger/recenttopicsng/styles/all/template/rtng_macros.html @@ -11,13 +11,14 @@ #} {% macro switch(name, checked = false, type = null) -%} - {% set type = type ?? TOGGLECTRL_TYPE ?? 'toggle' -%} - {% if type == 'toggle' || type == 'checkbox' -%} + {% set type = type ?? (TOGGLECTRL_TYPE in ['toggle', 'checkbox', 'radio'] ? TOGGLECTRL_TYPE : 'toggle') -%} + {% if type in ['toggle', 'checkbox'] -%} {%- elseif type == 'radio' -%} {%- endif %} + {#- v1.3.1 #} {%- endmacro %} {% macro select(name, options, multiple = null, size = null) -%} From 14c4f3db12c386dc8c3b8036e1f15dc5a4738c91 Mon Sep 17 00:00:00 2001 From: Thorsten <88725484+IMC-GER@users.noreply.github.com> Date: Sat, 25 Apr 2026 23:11:52 +0200 Subject: [PATCH 6/7] v1.2.0-b6 - Topics will not be displayed if there is only one forum. - Improve sql query for unread posts - Fixed: Topics will not be displayed if there is only one forum. --- imcger/recenttopicsng/composer.json | 4 ++-- imcger/recenttopicsng/core/rtng_functions.php | 16 +++------------- imcger/recenttopicsng/docs/CHANGELOG.md | 3 ++- 3 files changed, 7 insertions(+), 16 deletions(-) diff --git a/imcger/recenttopicsng/composer.json b/imcger/recenttopicsng/composer.json index 3ab4016..6d77b2e 100644 --- a/imcger/recenttopicsng/composer.json +++ b/imcger/recenttopicsng/composer.json @@ -3,8 +3,8 @@ "type": "phpbb-extension", "description": "Adds a list with a number of recent topics to the board index.", "homepage": "https://github.com/IMC-GER/RecentTopicsNG", - "version": "1.2.0-b5", - "time": "2026-04-07", + "version": "1.2.0-b6", + "time": "2026-05-25", "license": "GPL-2.0-only", "authors": [ { diff --git a/imcger/recenttopicsng/core/rtng_functions.php b/imcger/recenttopicsng/core/rtng_functions.php index eb21bbf..1b11fdc 100644 --- a/imcger/recenttopicsng/core/rtng_functions.php +++ b/imcger/recenttopicsng/core/rtng_functions.php @@ -212,7 +212,7 @@ private function getforumlist(): array $forum_ids = array_diff($forum_ary, $this->user->get_passworded_forums()); - if (count($forum_ids) > 1) + if (count($forum_ids) > 0) { $sql_array = [ 'SELECT' => 'forum_id', @@ -684,10 +684,6 @@ public function get_first_unread_post_data(array $topic_list): array p.post_id, p.post_subject, p.post_time, COUNT(p.topic_id) AS unread_post_counter', 'FROM' => [POSTS_TABLE => 'p', ], 'LEFT_JOIN' => [ - [ - 'FROM' => [TOPICS_TABLE => 't', ], - 'ON' => "t.topic_id = p.topic_id", - ], [ 'FROM' => [TOPICS_TRACK_TABLE => 'tt', ], 'ON' => "tt.user_id = {$this->user->data['user_id']} @@ -696,7 +692,7 @@ public function get_first_unread_post_data(array $topic_list): array [ 'FROM' => [FORUMS_TRACK_TABLE => 'ft', ], 'ON' => "ft.user_id = {$this->user->data['user_id']} - AND ft.forum_id = t.forum_id", + AND ft.forum_id = p.forum_id", ], [ 'FROM' => [USERS_TABLE => 'u', ], @@ -714,13 +710,7 @@ public function get_first_unread_post_data(array $topic_list): array $row_set = $this->db->sql_fetchrowset($result); $this->db->sql_freeresult($result); - $first_unread_posts = []; - foreach ($row_set as $row) - { - $first_unread_posts[$row['topic_id']] = $row; - } - - return $first_unread_posts; + return array_combine(array_column($row_set, 'topic_id'), $row_set); } public function validate_start(int $start, int $per_page, int $num_items): int diff --git a/imcger/recenttopicsng/docs/CHANGELOG.md b/imcger/recenttopicsng/docs/CHANGELOG.md index a1896ad..8471fea 100644 --- a/imcger/recenttopicsng/docs/CHANGELOG.md +++ b/imcger/recenttopicsng/docs/CHANGELOG.md @@ -1,4 +1,4 @@ -## Changelog Recent Topics NG V1.2.0-b4 +## Changelog Recent Topics NG V1.2.0-b6 This is a non-exhaustive (but still near complete) changelog for Recent Topics NG 1.x including release candidate versions. #### Changes since V1.1.0 (05/04/2026) @@ -10,6 +10,7 @@ This is a non-exhaustive (but still near complete) changelog for Recent Topics N - [Feature] Added vars in event `modify_tpl_ary`. `$s_type_switch` and `$s_type_switch_test`. - [Feature] Added event `topic_row_after `in `rtng_functions\fill_template`. - [Feature] The number of unread posts has been added to the tooltip when the RTNG switch in the Load Settings menu is enabled. + - [Fixed] Topics will not be displayed if there is only one forum. #### Changes since V1.0.1 (08/03/2026) - [Change] Classes have been switched to constructor property promotion. From e7bed2d496c912aadbffbbc8f6f21c9a18564adc Mon Sep 17 00:00:00 2001 From: Thorsten <88725484+IMC-GER@users.noreply.github.com> Date: Fri, 1 May 2026 22:01:25 +0200 Subject: [PATCH 7/7] v1.2.0 - Removed unnecessary ternary operator --- imcger/recenttopicsng/README.md | 4 ++-- imcger/recenttopicsng/composer.json | 4 ++-- imcger/recenttopicsng/core/rtng_functions.php | 2 +- imcger/recenttopicsng/docs/CHANGELOG.md | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/imcger/recenttopicsng/README.md b/imcger/recenttopicsng/README.md index caab752..c1521d0 100644 --- a/imcger/recenttopicsng/README.md +++ b/imcger/recenttopicsng/README.md @@ -8,8 +8,8 @@ Based on NV Recent Topics for phpBB 3.0, by Joas Schilling ([nickvergessen](http [![Tests](https://github.com/IMC-GER/RecentTopicsNG/actions/workflows/tests.yml/badge.svg)](https://github.com/IMC-GER/RecentTopicsNG/actions/workflows/tests.yml) ### Version -* v1.1.0 -* 08/03/2026 +* v1.2.0 +* 01/05/2026 ### Requirements * phpBB 3.3.5 - 3.3.x diff --git a/imcger/recenttopicsng/composer.json b/imcger/recenttopicsng/composer.json index 6d77b2e..ee4431f 100644 --- a/imcger/recenttopicsng/composer.json +++ b/imcger/recenttopicsng/composer.json @@ -3,8 +3,8 @@ "type": "phpbb-extension", "description": "Adds a list with a number of recent topics to the board index.", "homepage": "https://github.com/IMC-GER/RecentTopicsNG", - "version": "1.2.0-b6", - "time": "2026-05-25", + "version": "1.2.0", + "time": "2026-05-01", "license": "GPL-2.0-only", "authors": [ { diff --git a/imcger/recenttopicsng/core/rtng_functions.php b/imcger/recenttopicsng/core/rtng_functions.php index 1b11fdc..44ff734 100644 --- a/imcger/recenttopicsng/core/rtng_functions.php +++ b/imcger/recenttopicsng/core/rtng_functions.php @@ -469,7 +469,7 @@ private function fill_template(array $icons, string $tpl_loopname, array $topic_ $forum_id = $row['forum_id']; $unread_topic = false; $replies = $this->content_visibility->get_count('topic_posts', $row, $forum_id) - 1; - $s_type_switch_test = ($row['topic_type'] == POST_ANNOUNCE || $row['topic_type'] == POST_GLOBAL) ? true : false; + $s_type_switch_test = ($row['topic_type'] == POST_ANNOUNCE || $row['topic_type'] == POST_GLOBAL); $disp_topic_title = $this->user_setting['user_rtng_disp_last_post'] ? 'last_post' : 'first_post'; if (isset($first_unread_post_data[$topic_id])) diff --git a/imcger/recenttopicsng/docs/CHANGELOG.md b/imcger/recenttopicsng/docs/CHANGELOG.md index 8471fea..ee224f0 100644 --- a/imcger/recenttopicsng/docs/CHANGELOG.md +++ b/imcger/recenttopicsng/docs/CHANGELOG.md @@ -1,7 +1,7 @@ -## Changelog Recent Topics NG V1.2.0-b6 +## Changelog Recent Topics NG V1.2.0 This is a non-exhaustive (but still near complete) changelog for Recent Topics NG 1.x including release candidate versions. -#### Changes since V1.1.0 (05/04/2026) +#### Changes since V1.1.0 (01/05/2026) - [Change] Template vars for topic parents moved into `$tpl_ary`. - [Change] Improve the code for the pagination URL parameters. - [Chamge] Updated the `switch()` macro to the version of TC 1.3.