diff --git a/imcger/recenttopicsng/README.md b/imcger/recenttopicsng/README.md index 6d2a9b6..caab752 100644 --- a/imcger/recenttopicsng/README.md +++ b/imcger/recenttopicsng/README.md @@ -7,9 +7,13 @@ 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 + ### Requirements * phpBB 3.3.5 - 3.3.x -* PHP 7.4.0 - 8.4.x +* PHP 8.0 - 8.5.x ### Supported Style * Prosilver @@ -23,6 +27,7 @@ Based on NV Recent Topics for phpBB 3.0, by Joas Schilling ([nickvergessen](http * [User administration](https://raw.githubusercontent.com/IMC-GER/images/main/screenshots/recenttopicsng/rtng_user_administration.jpg) * [ACP settings](https://raw.githubusercontent.com/IMC-GER/images/main/screenshots/recenttopicsng/rtng_acp_settings.jpg) * [ACP edit forum](https://raw.githubusercontent.com/IMC-GER/images/main/screenshots/recenttopicsng/rtng_edit_forum.jpg) +* [ACP server load](https://raw.githubusercontent.com/IMC-GER/images/main/screenshots/recenttopicsng/rtng_acp_load_settings.jpg) ### Authors * © 2022 - IMC-GER & LukeWCS diff --git a/imcger/recenttopicsng/adm/style/acp_rtng.html b/imcger/recenttopicsng/adm/style/acp_rtng.html index f776249..e825ecb 100644 --- a/imcger/recenttopicsng/adm/style/acp_rtng.html +++ b/imcger/recenttopicsng/adm/style/acp_rtng.html @@ -15,10 +15,10 @@ {% include 'overall_header.html' %} -

{{ lang('RTNG_NAME') }}

-

{{ lang('RTNG_EXPLAIN') }}

+

{{ lang('RTNG_TITLE') }}

+

{{ lang('RTNG_EXPLAIN', RTNG_EXT_NAME) }}

-
+
{{ lang('RTNG_GLOBAL_SETTINGS') }} @@ -89,6 +89,9 @@

{{ lang('RTNG_NAME') }}

{{ lang('RTNG_OVERRIDABLE') }} +

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

+ +
{% include '@imcger_recenttopicsng/rtng_user_settings.html' %} @@ -119,8 +122,8 @@

{{ lang('RTNG_NAME') }}

{% include 'overall_footer.html' %} diff --git a/imcger/recenttopicsng/composer.json b/imcger/recenttopicsng/composer.json index 82654f4..966d565 100644 --- a/imcger/recenttopicsng/composer.json +++ b/imcger/recenttopicsng/composer.json @@ -3,20 +3,20 @@ "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.0.1", - "time": "2025-09-27", + "version": "1.1.0", + "time": "2026-03-08", "license": "GPL-2.0-only", "authors": [ - { - "name": "Thorsten Ahlers", - "homepage": "https://github.com/IMC-GER", - "role": "Developer" - }, - { - "name": "LukeWCS", - "homepage": "https://github.com/LukeWCS", - "role": "Developer" - }, + { + "name": "Thorsten Ahlers", + "homepage": "https://github.com/IMC-GER", + "role": "Developer" + }, + { + "name": "LukeWCS", + "homepage": "https://github.com/LukeWCS", + "role": "Developer" + }, { "name": "Andreas Vandenberghe", "homepage": "https://www.avathar.be", @@ -32,7 +32,7 @@ } ], "require": { - "php": ">=7.4,<8.5.0@dev", + "php": ">=8.0,<8.6.0@dev", "composer/installers": "~1.0" }, "extra": { diff --git a/imcger/recenttopicsng/config/services.yml b/imcger/recenttopicsng/config/services.yml index a6a3483..e3b4990 100644 --- a/imcger/recenttopicsng/config/services.yml +++ b/imcger/recenttopicsng/config/services.yml @@ -8,9 +8,9 @@ services: - '@language' - '@auth' - '@imcger.recenttopicsng.functions' + - '@imcger.recenttopicsng.controller_common' - '%core.root_path%' - '%core.php_ext%' - - '@imcger.recenttopicsng.controller_common' imcger.recenttopicsng.admin.controller: class: imcger\recenttopicsng\controller\admin_controller @@ -19,10 +19,12 @@ services: - '@template' - '@language' - '@request' - - '@dbal.conn' - - '@ext.manager' + - '@dbal.conn' + - '@cache.driver' - '@controller.helper' - '@imcger.recenttopicsng.controller_common' + - '%core.root_path%' + - '%core.php_ext%' imcger.recenttopicsng.controller_common: class: imcger\recenttopicsng\controller\controller_common @@ -30,6 +32,8 @@ services: - '@user' - '@auth' - '@dbal.conn' + - '@config' + - '@ext.manager' imcger.recenttopicsng.functions: class: imcger\recenttopicsng\core\rtng_functions @@ -45,10 +49,9 @@ services: - '@request' - '@template' - '@user' + - '@imcger.recenttopicsng.controller_common' - '%core.root_path%' - '%core.php_ext%' - - '@imcger.recenttopicsng.controller_common' - - '@?phpbb.collapsiblecategories.operator' imcger.recenttopicsng.main_listener: class: imcger\recenttopicsng\event\main_listener @@ -59,6 +62,7 @@ services: - '@language' - '@auth' - '@imcger.recenttopicsng.controller_common' + - '@?phpbb.collapsiblecategories.operator' tags: - { name: event.listener } diff --git a/imcger/recenttopicsng/controller/admin_controller.php b/imcger/recenttopicsng/controller/admin_controller.php index 42c70c2..2355cde 100644 --- a/imcger/recenttopicsng/controller/admin_controller.php +++ b/imcger/recenttopicsng/controller/admin_controller.php @@ -15,36 +15,22 @@ class admin_controller { - protected object $config; - protected object $template; - protected object $language; - protected object $request; - protected object $db; - protected object $ext_manager; - protected object $helper; - protected object $ctrl_common; protected string $u_action; public function __construct ( - \phpbb\config\config $config, - \phpbb\template\template $template, - \phpbb\language\language $language, - \phpbb\request\request $request, - \phpbb\db\driver\driver_interface $db, - \phpbb\extension\manager $ext_manager, - \phpbb\controller\helper $helper, - \imcger\recenttopicsng\controller\controller_common $controller_common + protected \phpbb\config\config $config, + protected \phpbb\template\template $template, + protected \phpbb\language\language $language, + protected \phpbb\request\request $request, + protected \phpbb\db\driver\driver_interface $db, + protected \phpbb\cache\driver\driver_interface $cache, + protected \phpbb\controller\helper $helper, + protected \imcger\recenttopicsng\controller\controller_common $ctrl_common, + protected $phpbb_root_path, + protected $phpEx, ) { - $this->config = $config; - $this->template = $template; - $this->language = $language; - $this->request = $request; - $this->db = $db; - $this->ext_manager = $ext_manager; - $this->helper = $helper; - $this->ctrl_common = $controller_common; } /** @@ -90,18 +76,19 @@ public function set_page_url(string $u_action): void */ protected function set_template_vars(): void { - $metadata_manager = $this->ext_manager->create_extension_metadata_manager('imcger/recenttopicsng'); - - $board_url = generate_board_url(true); - $simple_page_path = $this->helper->route('imcger_recenttopicsng_page_controller', ['page' => 'simple']); - $simple_page_url = $board_url . explode('?', $simple_page_path)[0]; + $metadata = $this->ctrl_common->get_rtng_composer_data(); + $board_url = generate_board_url(true); + $simple_page_path = $this->helper->route('imcger_recenttopicsng_page_controller', ['page' => 'simple']); + $simple_page_url = $board_url . explode('?', $simple_page_path)[0]; + $server_load_url = append_sid("{$this->phpbb_root_path}adm/index.{$this->phpEx}", 'i=acp_board&mode=load') . '#rtng_load_first_unrd_post'; $this->template->assign_vars([ 'U_ACTION' => $this->u_action, 'U_RTNG_PAGE_SIMPLE' => $simple_page_url, + 'U_SERVER_LOAD' => $server_load_url, - 'RTNG_NAME' => $metadata_manager->get_metadata('display-name'), - 'RTNG_EXT_VER' => $metadata_manager->get_metadata('version'), + 'RTNG_EXT_NAME' => $metadata['extra']['display-name'], + 'RTNG_EXT_VER' => $metadata['version'], 'RTNG_ANTI_TOPICS' => $this->config['rtng_anti_topics'], 'RTNG_PARENTS' => (int) $this->config['rtng_parents'], @@ -172,5 +159,7 @@ protected function set_vars_usertable(bool $all_user): void SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . $sql_where; $this->db->sql_query($sql); + + $this->cache->destroy('sql', USERS_TABLE); } } diff --git a/imcger/recenttopicsng/controller/controller_common.php b/imcger/recenttopicsng/controller/controller_common.php index cc2d062..eaaf971 100644 --- a/imcger/recenttopicsng/controller/controller_common.php +++ b/imcger/recenttopicsng/controller/controller_common.php @@ -15,20 +15,18 @@ class controller_common { - protected object $user; - protected object $auth; - protected object $db; + protected array $rtng_user_data; public function __construct ( - \phpbb\user $user, - \phpbb\auth\auth $auth, - \phpbb\db\driver\driver_interface $db + protected \phpbb\user $user, + protected \phpbb\auth\auth $auth, + protected \phpbb\db\driver\driver_interface $db, + protected \phpbb\config\config $config, + protected \phpbb\extension\manager $ext_manager, ) { - $this->user = $user; - $this->auth = $auth; - $this->db = $db; + $this->set_rtng_user_data($user->data); } /* @@ -65,9 +63,9 @@ public function get_user_set_template_vars(int $user_id, array $template_setting { if ($user_id != $this->user->data['user_id']) { - $user_auth = new \phpbb\auth\auth(); - $userdata = $user_auth->obtain_user_data($user_id); - $user_auth->acl($userdata); + $user_auth = new \phpbb\auth\auth(); + $auth_userdata = $user_auth->obtain_user_data($user_id); + $user_auth->acl($auth_userdata); } else { @@ -108,12 +106,12 @@ public function get_user_set_template_vars(int $user_id, array $template_setting if ($user_auth->acl_get('u_rtng_disp_last_post') || $uaec) { $template_vars['RTNG_DISP_LAST_POST_OPTIONS'] = $this->select_struct((int) $template_setting['user_rtng_disp_last_post'], [ - 'RTNG_FIRST_POST' => 0, - 'RTNG_LAST_POST' => 1, + 'RTNG_FIRST_POST' => 0, + 'RTNG_LAST_POST' => 1, ]); } - if ($user_auth->acl_get('u_rtng_disp_first_unrd_post') || $uaec) + if (($user_auth->acl_get('u_rtng_disp_first_unrd_post') || $uaec) && ($this->config['rtng_load_first_unrd_post'] && $this->config['load_db_lastread'])) { $template_vars['RTNG_DISP_FIRST_UNRD_POST'] = $template_setting['user_rtng_disp_first_unrd_post']; } @@ -154,11 +152,40 @@ public function get_user_set_template_vars(int $user_id, array $template_setting return $template_vars; } + /** + * Store user data in cache array + */ + public function set_rtng_user_data(array $user_data): bool + { + if (empty($user_data['user_id'])) + { + return false; + } + + $this->rtng_user_data[$user_data['user_id']] = []; + + foreach ($user_data as $key => $value) + { + if (str_starts_with($key, 'user_rtng')) + { + $this->rtng_user_data[$user_data['user_id']][$key] = $value; + } + } + + return true; + } + /** * Returns the RTNG user data. + * Cache user data in an array */ public function get_rtng_user_data(int $user_id = ANONYMOUS): array { + if (isset($this->rtng_user_data[$user_id])) + { + return $this->rtng_user_data[$user_id]; + } + $sql_array = [ 'SELECT' => 'user_rtng_enable, user_rtng_sort_start_time, user_rtng_unread_only, user_rtng_location, user_rtng_disp_last_post, user_rtng_disp_first_unrd_post, @@ -168,99 +195,59 @@ public function get_rtng_user_data(int $user_id = ANONYMOUS): array 'WHERE' => 'user_id = ' . (int) $user_id, ]; - $sql = $this->db->sql_build_query('SELECT', $sql_array); - $result = $this->db->sql_query_limit($sql, 1); - $data = $this->db->sql_fetchrow($result); + $sql = $this->db->sql_build_query('SELECT', $sql_array); + $cache_time = $user_id == ANONYMOUS ? 3600 : 0; + $result = $this->db->sql_query($sql, $cache_time); + $this->rtng_user_data[$user_id] = $this->db->sql_fetchrow($result); $this->db->sql_freeresult($result); - return $data; + return $this->rtng_user_data[$user_id]; } /** - * Returns the RTNG user settings depending on the user authorizations. + * Returns the RTNG user settings depending on the user permission. */ - public function get_user_setting(?int $user_id = null): array + public function get_user_setting(int $user_id = 0): array { - $default_data = $this->get_rtng_user_data(); - - if (isset($user_id)) - { - $user_data = $this->get_rtng_user_data($user_id); - } - else - { - $user_id = $this->user->data['user_id']; - $user_data = $this->user->data; - } + $user_id = $user_id ?: $this->user->data['user_id']; + $default_data = $this->get_rtng_user_data(ANONYMOUS); if ($user_id == ANONYMOUS) { return $default_data; } + $user_data = $this->get_rtng_user_data($user_id); + if ($user_id != $this->user->data['user_id']) { - $user_auth = new \phpbb\auth\auth(); - $userdata = $user_auth->obtain_user_data($user_id); - $user_auth->acl($userdata); + $user_auth = new \phpbb\auth\auth(); + $auth_userdata = $user_auth->obtain_user_data($user_id); + $user_auth->acl($auth_userdata); } else { $user_auth = $this->auth; } - if ($user_auth->acl_get('u_rtng_enable')) - { - $default_data['user_rtng_enable'] = $user_data['user_rtng_enable']; - } - - if ($user_auth->acl_get('u_rtng_sort_start_time')) - { - $default_data['user_rtng_sort_start_time'] = $user_data['user_rtng_sort_start_time']; - } - - if ($user_auth->acl_get('u_rtng_unread_only')) - { - $default_data['user_rtng_unread_only'] = $user_data['user_rtng_unread_only']; - } - - if ($user_auth->acl_get('u_rtng_location')) + foreach ($default_data as $key => $value) { - $default_data['user_rtng_location'] = $user_data['user_rtng_location']; - } - - if ($user_auth->acl_get('u_rtng_disp_last_post')) - { - $default_data['user_rtng_disp_last_post'] = $user_data['user_rtng_disp_last_post']; - } - - if ($user_auth->acl_get('u_rtng_disp_first_unrd_post')) - { - $default_data['user_rtng_disp_first_unrd_post'] = $user_data['user_rtng_disp_first_unrd_post']; - } - - if ($user_auth->acl_get('u_rtng_index_topics_qty')) - { - $default_data['user_rtng_index_topics_qty'] = $user_data['user_rtng_index_topics_qty']; - } - - if ($user_auth->acl_get('u_rtng_index_page_qty')) - { - $default_data['user_rtng_index_page_qty'] = $user_data['user_rtng_index_page_qty']; - } - - if ($user_auth->acl_get('u_rtng_separate_topics_qty')) - { - $default_data['user_rtng_separate_topics_qty'] = $user_data['user_rtng_separate_topics_qty']; - } - - if ($user_auth->acl_get('u_rtng_separate_page_qty')) - { - $default_data['user_rtng_separate_page_qty'] = $user_data['user_rtng_separate_page_qty']; + if ($user_auth->acl_get('u_' . substr($key, 5))) + { + $default_data[$key] = $user_data[$key]; + } } unset($user_auth); return $default_data; } + + /** + * Returns the RTNG composer data. + */ + public function get_rtng_composer_data(): array + { + return $this->ext_manager->create_extension_metadata_manager('imcger/recenttopicsng')->get_metadata('all'); + } } diff --git a/imcger/recenttopicsng/controller/page_controller.php b/imcger/recenttopicsng/controller/page_controller.php index fca8abe..c2ed3fd 100644 --- a/imcger/recenttopicsng/controller/page_controller.php +++ b/imcger/recenttopicsng/controller/page_controller.php @@ -15,38 +15,19 @@ class page_controller { - protected object $config; - protected object $template; - protected object $helper; - protected object $language; - protected object $auth; - protected object $rtng_functions; - protected object $ctrl_common; - protected string $phpbb_root_path; - protected string $phpEx; - public function __construct ( - \phpbb\config\config $config, - \phpbb\template\template $template, - \phpbb\controller\helper $helper, - \phpbb\language\language $language, - \phpbb\auth\auth $auth, - \imcger\recenttopicsng\core\rtng_functions $rtng_functions, - $phpbb_root_path, - $phpEx, - \imcger\recenttopicsng\controller\controller_common $controller_common + protected \phpbb\config\config $config, + protected \phpbb\template\template $template, + protected \phpbb\controller\helper $helper, + protected \phpbb\language\language $language, + protected \phpbb\auth\auth $auth, + protected \imcger\recenttopicsng\core\rtng_functions $rtng_functions, + protected \imcger\recenttopicsng\controller\controller_common $ctrl_common, + protected $phpbb_root_path, + protected $phpEx, ) { - $this->config = $config; - $this->template = $template; - $this->helper = $helper; - $this->language = $language; - $this->auth = $auth; - $this->rtng_functions = $rtng_functions; - $this->phpbb_root_path = $phpbb_root_path; - $this->phpEx = $phpEx; - $this->ctrl_common = $controller_common; } /** @@ -55,9 +36,8 @@ public function __construct public function display(string $page): object { $this->language->add_lang('rtng_common', 'imcger/recenttopicsng'); - $title = $this->language->lang('RTNG_DESIG'); - $user_setting = $this->ctrl_common->get_user_setting(); + $title = $this->language->lang('RTNG' . ($user_setting['user_rtng_unread_only'] ? '_UNREAD' : '') . '_TITLE'); // Redirect to index site when user has no permisson if (!($user_setting['user_rtng_enable'] && $this->auth->acl_get('u_rtng_view'))) @@ -97,13 +77,18 @@ public function display(string $page): object make_jumpbox(append_sid($this->phpbb_root_path . 'viewforum.' . $this->phpEx)); // Generate link in NavBar - $this->template->assign_block_vars('navlinks', [ - 'BREADCRUMB_NAME' => $this->language->lang('RTNG_DESIG'), + $navlinks = []; + $navlinks[] = [ + 'BREADCRUMB_NAME' => $title, 'U_BREADCRUMB' => $this->helper->route('imcger_recenttopicsng_page_controller', ['page' => 'separate']), + ]; + + $this->template->assign_vars([ + 'navlinks' => $navlinks, + 'U_CANONICAL' => $this->helper->route('imcger_recenttopicsng_page_controller', ['page' => 'separate'], true, false, \Symfony\Component\Routing\Generator\UrlGeneratorInterface::ABSOLUTE_URL), ]); $this->rtng_functions->display_recent_topics(); - break; // Displays the start page of phpBB diff --git a/imcger/recenttopicsng/core/rtng_functions.php b/imcger/recenttopicsng/core/rtng_functions.php index d796b64..ec0d459 100644 --- a/imcger/recenttopicsng/core/rtng_functions.php +++ b/imcger/recenttopicsng/core/rtng_functions.php @@ -15,64 +15,32 @@ class rtng_functions { - protected object $auth; - protected object $config; - protected object $language; - protected object $cache; - protected object $content_visibility; - protected object $db; - protected object $dispatcher; - protected object $pagination; - protected object $request; - protected object $template; - protected object $user; - protected string $root_path; - protected string $phpEx; - protected object $ctrl_common; - private ?object $collapsable_categories; // var support extension "Collapsible Forum Categories" private array $user_setting; + private int $topics_start; private int $topics_per_page; private int $topics_page_number; public function __construct ( - \phpbb\auth\auth $auth, - \phpbb\cache\service $cache, - \phpbb\config\config $config, - \phpbb\language\language $language, - \phpbb\content_visibility $content_visibility, - \phpbb\db\driver\driver_interface $db, - \phpbb\event\dispatcher_interface $dispatcher, - \phpbb\pagination $pagination, - \phpbb\request\request_interface $request, - \phpbb\template\template $template, - \phpbb\user $user, - $root_path, - $phpEx, - \imcger\recenttopicsng\controller\controller_common $controller_common, - ?\phpbb\collapsiblecategories\operator\operator $collapsable_categories = null + protected \phpbb\auth\auth $auth, + protected \phpbb\cache\service $cache, + protected \phpbb\config\config $config, + protected \phpbb\language\language $language, + protected \phpbb\content_visibility $content_visibility, + protected \phpbb\db\driver\driver_interface $db, + protected \phpbb\event\dispatcher_interface $dispatcher, + protected \phpbb\pagination $pagination, + protected \phpbb\request\request_interface $request, + protected \phpbb\template\template $template, + protected \phpbb\user $user, + protected \imcger\recenttopicsng\controller\controller_common $ctrl_common, + protected $root_path, + protected $phpEx, ) { - $this->auth = $auth; - $this->cache = $cache; - $this->config = $config; - $this->language = $language; - $this->content_visibility = $content_visibility; - $this->db = $db; - $this->dispatcher = $dispatcher; - $this->pagination = $pagination; - $this->request = $request; - $this->template = $template; - $this->user = $user; - $this->root_path = $root_path; - $this->phpEx = $phpEx; - $this->ctrl_common = $controller_common; - $this->collapsable_categories = $collapsable_categories; - + $this->topics_start = 0; $this->topics_per_page = 0; $this->topics_page_number = 0; - - $this->user_setting = $this->ctrl_common->get_user_setting(); } /** @@ -106,8 +74,10 @@ public function set_topics_page_number(int $page_number): bool /** * Display recent topics */ - public function display_recent_topics(string $tpl_loopname = 'rtng'): void + public function display_recent_topics(string $tpl_loopname = 'rtng_topics'): void { + $this->user_setting = $this->ctrl_common->get_user_setting(); + // can view rtng ? if (!($this->user_setting['user_rtng_enable'] && $this->auth->acl_get('u_rtng_view'))) { @@ -119,22 +89,21 @@ public function display_recent_topics(string $tpl_loopname = 'rtng'): void include($this->root_path . 'includes/functions_display.' . $this->phpEx); } - // support for phpbb collapsable categories extension - if (isset($this->collapsable_categories)) - { - $fid = 'fid_rtng'; // can be any unique string to identify the collapsible element of your extension. - $this->template->assign_vars([ - 'S_EXT_COLCAT_HIDDEN' => $this->collapsable_categories->is_collapsed($fid), - 'U_EXT_COLCAT_COLLAPSE_URL' => $this->collapsable_categories->get_collapsible_link($fid), - ]); - } - $rtng_start = $this->request->variable($tpl_loopname . '_start', 0); $excluded_topics = explode(',', $this->config['rtng_anti_topics']); $min_topic_level = $this->config['rtng_min_topic_level']; + $this->language->add_lang('rtng_common', 'imcger/recenttopicsng'); + $this->template->assign_vars([ + 'S_RTNG_LOCATION_TOP' => $this->user_setting['user_rtng_location'] == 'RTNG_TOP', + 'S_RTNG_LOCATION_BOTTOM' => $this->user_setting['user_rtng_location'] == 'RTNG_BOTTOM', + 'S_RTNG_LOCATION_SIDE' => $this->user_setting['user_rtng_location'] == 'RTNG_SIDE', + strtoupper($tpl_loopname) . '_DISPLAY' => true, + ] + ); + $forum_id_list = $this->getforumlist(); // No forums to display @@ -167,6 +136,7 @@ public function display_recent_topics(string $tpl_loopname = 'rtng'): void $count_sql_array = $sql_array; $count_sql_array['SELECT'] = 'COUNT(t.topic_id) as topic_count'; unset($count_sql_array['ORDER_BY']); + unset($count_sql_array['LEFT_JOIN']); $sql = $this->db->sql_build_query('SELECT', $count_sql_array); $result = $this->db->sql_query($sql); @@ -179,6 +149,12 @@ public function display_recent_topics(string $tpl_loopname = 'rtng'): void $forums = []; $topic_list = []; + // When 0 there are no topics to display + if ($total_topics_limit < 1) + { + return; + } + $topics_count = $this->gettopiclist($obtain_icons, $forums, $rtng_start, $total_topics_limit, $excluded_topics, $forum_id_list, $topic_list); // Return if there are no topics available to display. @@ -194,48 +170,27 @@ public function display_recent_topics(string $tpl_loopname = 'rtng'): void $icons = $this->cache->obtain_icons(); } - // Borrowed from search.php + // Get the topic tracking data $topic_tracking_info = []; foreach ($forums as $forum_id => $forum) { - if ($this->user->data['is_registered'] && $this->config['load_db_lastread']) + if ($this->config['load_db_lastread'] && $this->user->data['is_registered'] && !$this->config['rtng_load_first_unrd_post']) { - $topic_tracking_info[$forum_id] = get_topic_tracking($forum_id, $forum['topic_list'], $forum['rowset'], [$forum_id => $forum['mark_time']], $forum_id ? false : $forum['topic_list']); + $topic_tracking_info[$forum_id] = get_topic_tracking($forum_id, $forum['topic_list'], $forum['rowset'], [$forum_id => $forum['mark_time']]); } - else if ($this->config['load_anon_lastread'] || $this->user->data['is_registered']) + else if ($this->config['load_anon_lastread'] || ($this->user->data['is_registered'] && !$this->config['load_db_lastread'])) { - $tracking_topics = $this->request->variable($this->config['cookie_name'] . '_track', '', true, \phpbb\request\request_interface::COOKIE); - $tracking_topics = $tracking_topics ? tracking_unserialize($tracking_topics) : []; - - $topic_tracking_info[$forum_id] = get_complete_topic_tracking($forum_id, $forum['topic_list'], $forum_id ? false : $forum['topic_list']); - - if (!$this->user->data['is_registered']) - { - if (isset($tracking_topics['l'])) - { - $this->user->data['user_lastmark'] = ( (int) base_convert($tracking_topics['l'], 36, 10) + (int) $this->config['board_startdate']); - } - else - { - $this->user->data['user_lastmark'] = 0; - } - } + $topic_tracking_info[$forum_id] = get_complete_topic_tracking($forum_id, $forum['topic_list']); } } - //load language - $this->language->add_lang('rtng_common', 'imcger/recenttopicsng'); $this->template->assign_vars([ 'RTNG_TOPICS_COUNT' => $this->language->lang('RTNG_TOPICS_COUNT', (int) $topics_count), 'RTNG_SORT_START_TIME' => $this->user_setting['user_rtng_sort_start_time'], - 'S_RTNG_LOCATION_TOP' => $this->user_setting['user_rtng_location'] == 'RTNG_TOP', - 'S_RTNG_LOCATION_BOTTOM' => $this->user_setting['user_rtng_location'] == 'RTNG_BOTTOM', - 'S_RTNG_LOCATION_SIDE' => $this->user_setting['user_rtng_location'] == 'RTNG_SIDE', - strtoupper($tpl_loopname) . '_DISPLAY' => true, ] ); - $this->fill_template($icons, $tpl_loopname, $topic_tracking_info, $topics_count, $topic_list, $total_topics_limit, $rtng_start); + $this->fill_template($icons, $tpl_loopname, $topic_tracking_info, $topics_count, $topic_list); } /** @@ -255,7 +210,7 @@ private function getforumlist(): array } } - $forum_ids = array_unique($forum_ary); + $forum_ids = array_diff($forum_ary, $this->user->get_passworded_forums()); if (count($forum_ids) > 1) { @@ -269,16 +224,12 @@ private function getforumlist(): array $sql = $this->db->sql_build_query('SELECT', $sql_array); $result = $this->db->sql_query($sql); - $forum_ids = []; - - while ($row = $this->db->sql_fetchrow($result)) - { - $forum_ids[] = $row['forum_id']; - } + $rows = $this->db->sql_fetchrowset($result); + $forum_ids_disp = array_column($rows, 'forum_id'); $this->db->sql_freeresult($result); - return array_unique($forum_ids); + return $forum_ids_disp; } else { @@ -291,35 +242,22 @@ private function getforumlist(): array */ private function gettopiclist(bool &$obtain_icons, array &$forums, int $rtng_start, int $total_topics_limit, array $excluded_topics, array $forum_id_list, array &$topic_list): int { - $rtng_start = max(0, $rtng_start); - - if ($total_topics_limit > 0) - { - $rtng_start = min((int) $rtng_start, $total_topics_limit); - } - - $topics_count = 0; - + $topics_count = 0; $min_topic_level = $this->config['rtng_min_topic_level']; // Either use the phpBB core function to get unread topics, or the custom function for default behavior - if ($this->user_setting['user_rtng_unread_only'] && $this->user->data['user_id'] != ANONYMOUS) + if ($this->user_setting['user_rtng_unread_only'] && $this->user->data['is_registered']) { // Get unread topics $sql_extra = ' AND ' . $this->db->sql_in_set('t.topic_id', $excluded_topics, true); $sql_extra .= ' AND ' . $this->content_visibility->get_forums_visibility_sql('topic', $forum_id_list, $table_alias = 't.'); + $sql_extra .= ' AND t.topic_status <> ' . ITEM_MOVED; $unread_topics = get_unread_topics(false, $sql_extra, '', $total_topics_limit); - $rtng_start = min(count($unread_topics) - 1 , (int) $rtng_start); - foreach ($unread_topics as $topic_id => $mark_time) - { - $topics_count++; + $total_topics_limit = min($total_topics_limit, count($unread_topics)); + $rtng_start = $this->validate_start($rtng_start, $this->topics_per_page, $total_topics_limit); - if (($topics_count > $rtng_start) && ($topics_count <= ($rtng_start + $this->topics_per_page))) - { - $topic_list[] = $topic_id; - } - } + $topic_list = array_slice(array_keys($unread_topics), $rtng_start, $this->topics_per_page); } else { @@ -328,61 +266,55 @@ private function gettopiclist(bool &$obtain_icons, array &$forums, int $rtng_sta $count_sql_array = $sql_array; $count_sql_array['SELECT'] = 'COUNT(t.topic_id) as topic_count'; unset($count_sql_array['ORDER_BY']); + unset($count_sql_array['LEFT_JOIN']); $sql = $this->db->sql_build_query('SELECT', $count_sql_array); $result = $this->db->sql_query($sql); - $num_rows = (int) $this->db->sql_fetchfield('topic_count'); + $topics_count = (int) $this->db->sql_fetchfield('topic_count'); $this->db->sql_freeresult($result); //load topics list $sql = $this->db->sql_build_query('SELECT', $sql_array); - if ($total_topics_limit > 0) - { - $result = $this->db->sql_query_limit($sql, $total_topics_limit); - } - else - { - $result = $this->db->sql_query($sql); - } + $total_topics_limit = min($total_topics_limit, $topics_count); + $rtng_start = $this->validate_start($rtng_start, $this->topics_per_page, $total_topics_limit); + $result = $this->db->sql_query_limit($sql, $this->topics_per_page, $rtng_start); - if ($result != null) - { - $rtng_start = min($num_rows - 1 , $rtng_start); - } - else + // Return 0 topics to display + if ($result == false) { - $rtng_start = 0; + return 0; } $rowset = []; while ($row = $this->db->sql_fetchrow($result)) { - $topics_count++; + $topic_list[] = $row['topic_id']; - if (($topics_count > $rtng_start) && ($topics_count <= ($rtng_start + $this->topics_per_page))) - { - $topic_list[] = $row['topic_id']; - - $rowset[$row['topic_id']] = $row; + $rowset[$row['topic_id']] = $row; - if (!isset($forums[$row['forum_id']]) && $this->user->data['is_registered'] && $this->config['load_db_lastread']) - { - $forums[$row['forum_id']]['mark_time'] = $row['f_mark_time']; - } - $forums[$row['forum_id']]['topic_list'][] = $row['topic_id']; - $forums[$row['forum_id']]['rowset'][$row['topic_id']] = & $rowset[$row['topic_id']]; + if (!isset($forums[$row['forum_id']]) && $this->user->data['is_registered'] && $this->config['load_db_lastread']) + { + $forums[$row['forum_id']]['mark_time'] = $row['f_mark_time']; + } + $forums[$row['forum_id']]['topic_list'][] = $row['topic_id']; + $forums[$row['forum_id']]['rowset'][$row['topic_id']] = & $rowset[$row['topic_id']]; - if ($row['icon_id']) - { - $obtain_icons = true; - } + if ($row['icon_id']) + { + $obtain_icons = true; } } + $this->db->sql_freeresult($result); } - return $topics_count; + + // Set start of pagination + $this->topics_start = $rtng_start; + + // Return number of total topics counts to display + return $total_topics_limit; } /** @@ -492,13 +424,9 @@ private function get_topics_sql(array $topic_list): array extract($this->dispatcher->trigger_event('imcger.recenttopicsng.sql_pull_topics_data', compact($vars))); $sql = $this->db->sql_build_query('SELECT', $sql_array); - $result = $this->db->sql_query_limit($sql, $this->topics_per_page); - $rowset = []; + $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - $rowset[] = $row; - } + $rowset = $this->db->sql_fetchrowset($result); $this->db->sql_freeresult($result); return $rowset; @@ -507,7 +435,7 @@ private function get_topics_sql(array $topic_list): array /** * Set template vars */ - private function fill_template(array $icons, string $tpl_loopname, array $topic_tracking_info, int $topics_count, array $topic_list, int $total_topics_limit, int $rtng_start): void + private function fill_template(array $icons, string $tpl_loopname, array $topic_tracking_info, int $topics_count, array $topic_list): void { // get topics from db $rowset = $this->get_topics_sql($topic_list); @@ -529,63 +457,34 @@ private function fill_template(array $icons, string $tpl_loopname, array $topic_ foreach ($rowset as $row) { - $topic_id = $row['topic_id']; - $forum_id = $row['forum_id']; + $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; - $replies = $this->content_visibility->get_count('topic_posts', $row, $forum_id) - 1; - - if ($row['topic_status'] == ITEM_MOVED) - { - $topic_id = $row['topic_moved_id']; - $unread_topic = false; - } - else - { - $unread_topic = (isset($topic_tracking_info[$forum_id][$row['topic_id']]) && $row['topic_last_post_time'] > $topic_tracking_info[$forum_id][$row['topic_id']]) ? true : false; - } - - // Get folder img, topic status/type related information - $folder_img = $folder_alt = $topic_type = ''; - - if ($this->user_setting['user_rtng_unread_only']) - { - topic_status($row, $replies, true, $folder_img, $folder_alt, $topic_type); - $unread_topic = $this->user->data['user_id'] != ANONYMOUS; - } - else - { - if (isset($topic_tracking_info[$forum_id][$row['topic_id']]) && $row['topic_last_post_time'] > $topic_tracking_info[$forum_id][$row['topic_id']]) - { - topic_status($row, $replies, true, $folder_img, $folder_alt, $topic_type); - } - else - { - topic_status($row, $replies, false, $folder_img, $folder_alt, $topic_type); - } + $disp_topic_title = $this->user_setting['user_rtng_disp_last_post'] ? 'last_post' : 'first_post'; - if (isset($topic_tracking_info[$forum_id][$row['topic_id']]) && $row['topic_last_post_time'] > $topic_tracking_info[$forum_id][$row['topic_id']]) - { - $unread_topic = true; - } - else - { - $unread_topic = false; - } - } - - $first_unread = []; - - if ($unread_topic && $this->user_setting['user_rtng_disp_first_unrd_post']) + if ($this->user->data['is_registered'] && $this->config['load_db_lastread'] && $this->config['rtng_load_first_unrd_post']) { // 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 = $topic_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', ], @@ -593,21 +492,41 @@ private function fill_template(array $icons, string $tpl_loopname, array $topic_ ], ], 'WHERE' => "p.topic_id = $topic_id - AND p.post_time > COALESCE(tt.mark_time, 0)", + 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); - $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']); + $unread_topic = !empty($first_unread['post_id']); + + if ($this->user_setting['user_rtng_disp_first_unrd_post'] && $unread_topic) + { + $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']); + } + } + else + { + $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'] ?? ''; + $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']) : ''; @@ -623,6 +542,13 @@ private function fill_template(array $icons, string $tpl_loopname, array $topic_ $topic_icons[] = $topic_id; } + if ($this->user_setting['user_rtng_unread_only'] && $this->user->data['is_registered']) + { + $unread_topic = true; + } + + // Get folder img, topic status/type related information + $folder_img = $folder_alt = $topic_type = ''; topic_status($row, $replies, $unread_topic, $folder_img, $folder_alt, $topic_type); 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); @@ -637,12 +563,12 @@ private function fill_template(array $icons, string $tpl_loopname, array $topic_ 'TOPIC_AUTHOR_FULL' => $topic_author_full, 'U_TOPIC_AUTHOR' => $u_topic_author, 'FIRST_POST_TIME' => $this->user->format_date($row['topic_time']), - 'FIRST_UNREAD_POST_AUTHOR' => !empty($first_unread_post_author) ? $first_unread_post_author : '', - 'FIRST_UNREAD_POST_AUTHOR_COLOUR' => !empty($first_unread_post_author_color) ? $first_unread_post_author_color : '', - 'FIRST_UNREAD_POST_AUTHOR_FULL' => !empty($first_unread_post_author_full) ? $first_unread_post_author_full : '', - 'U_FIRST_UNREAD_POST_AUTHOR' => !empty($u_first_unread_post_author) ? $u_first_unread_post_author : '', - 'FIRST_UNREAD_POST_SUBJECT' => censor_text(!empty($first_unread['post_subject']) ? $first_unread['post_subject'] : ''), - 'FIRST_UNREAD_POST_TIME' => !empty($first_unread_post_time) ? $first_unread_post_time : '', + 'FIRST_UNREAD_POST_AUTHOR' => $first_unread_post_author ?? '', + 'FIRST_UNREAD_POST_AUTHOR_COLOUR' => $first_unread_post_author_color ?? '', + 'FIRST_UNREAD_POST_AUTHOR_FULL' => $first_unread_post_author_full ?? '', + 'U_FIRST_UNREAD_POST_AUTHOR' => $u_first_unread_post_author ?? '', + 'FIRST_UNREAD_POST_SUBJECT' => censor_text($row['topic_first_unread_post_subject']), + 'FIRST_UNREAD_POST_TIME' => $first_unread_post_time ?? '', 'LAST_POST_SUBJECT' => censor_text($row['topic_last_post_subject']), 'LAST_POST_TIME' => $this->user->format_date($row['topic_last_post_time']), 'LAST_VIEW_TIME' => $this->user->format_date($row['topic_last_view_time']), @@ -664,11 +590,12 @@ private function fill_template(array $icons, string $tpl_loopname, array $topic_ 'ATTACH_ICON_IMG' => ($this->auth->acl_get('u_download') && $this->auth->acl_get('f_download', $forum_id) && $row['topic_attachment']) ? $this->user->img('icon_topic_attach', $this->language->lang('TOTAL_ATTACHMENTS')) : '', 'UNAPPROVED_IMG' => ($topic_unapproved || $posts_unapproved) ? $this->user->img('icon_topic_unapproved', $topic_unapproved ? 'TOPIC_UNAPPROVED' : 'POSTS_UNAPPROVED') : '', 'REPORTED_IMG' => ($row['topic_reported'] && $this->auth->acl_get('m_report', $forum_id)) ? $this->user->img('icon_topic_reported', 'TOPIC_REPORTED') : '', - 'S_HAS_POLL' => $row['poll_start'] ? true : false, + 'S_HAS_POLL' => (bool) $row['poll_start'], 'S_TOPIC_TYPE' => $row['topic_type'], 'S_UNREAD_TOPIC' => $unread_topic, - 'S_DISP_FIRST_UNREAD_POST' => $this->user_setting['user_rtng_disp_first_unrd_post'] && $unread_topic, - 'S_DISP_LAST_POST' => $this->user_setting['user_rtng_disp_last_post'], + 'S_DISP_FIRST_UNREAD_POST' => $disp_topic_title == 'first_unread_post', + 'S_DISP_LAST_POST' => $disp_topic_title == 'last_post', + 'S_DISP_FIRST_POST' => $disp_topic_title == 'first_post', 'S_TOPIC_REPORTED' => $row['topic_reported'] && $this->auth->acl_get('m_report', $forum_id), 'S_TOPIC_UNAPPROVED' => $topic_unapproved, 'S_POSTS_UNAPPROVED' => $posts_unapproved, @@ -691,11 +618,13 @@ private function fill_template(array $icons, string $tpl_loopname, array $topic_ * Modify the topic data before it is assigned to the template * * @event imcger.recenttopicsng.modify_tpl_ary - * @var array row Array with topic data - * @var array tpl_ary Template block array with topic data + * @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 * @since 1.0.0 + * @changed 1.1.0 Variables added. $disp_topic_title and properties of the first unread post in $row */ - $vars = ['row', 'tpl_ary']; + $vars = ['disp_topic_title', 'row', 'tpl_ary']; extract($this->dispatcher->trigger_event('imcger.recenttopicsng.modify_tpl_ary', compact($vars))); $this->template->assign_block_vars($tpl_loopname, $tpl_ary); @@ -745,11 +674,20 @@ private function fill_template(array $icons, string $tpl_loopname, array $topic_ $pagination_url = append_sid($this->root_path . $this->user->page['page_name'], $append_params); $this->pagination->generate_template_pagination($pagination_url, 'pagination', - $tpl_loopname . '_start', $topics_count, $this->topics_per_page, max(0, min((int) $rtng_start, $total_topics_limit))); + $tpl_loopname . '_start', $topics_count, $this->topics_per_page, $this->topics_start); $this->template->assign_vars([ - 'S_RTNG_TOPIC_ICONS' => count($topic_icons) ? true : false, + 'S_RTNG_TOPIC_ICONS' => (bool) $topic_icons, ]); } // topics found } + + public function validate_start($start, $per_page, $num_items) + { + $start = $start >= $num_items ? $num_items - 1 : $start; + $start = intdiv($start, $per_page) * $per_page; + $start = max(0, $start); + + return $start; + } } diff --git a/imcger/recenttopicsng/docs/CHANGELOG.md b/imcger/recenttopicsng/docs/CHANGELOG.md index 68854ec..673b753 100644 --- a/imcger/recenttopicsng/docs/CHANGELOG.md +++ b/imcger/recenttopicsng/docs/CHANGELOG.md @@ -1,6 +1,35 @@ -## Changelog Recent Topics NG V1.0.1 +## Changelog Recent Topics NG V1.1.0 This is a non-exhaustive (but still near complete) changelog for Recent Topics NG 1.x including release candidate versions. +#### 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. + - [Change] The metadata is used to display the extension name.. + - [Change] php min to v8.0. + - [Change] Cached “rtng_user_data” reduces DB queries. + - [Change] Improved SQL query for topic counting for better performance. + - [Change] assign_block_vars() replaced in page_controller. + - [Change] phpBB template code replaced with Twig syntax. + - [Change] Optimization of loops that adjust arrays in `rtng_functions`. + - [Change] Only reads the topics that are necessary to load the page. + - [Change] Required tag in number macro in `rtng_macros.html` added. + - [Change] Var name $num_rows to $topics_count. + - [Change] Improved vars for `sql_query_limit()`. + - [Change] Better support for phpBB Collapsed Categories. + - [Change] Improved sql query for first unread post. + - [Change] Improved explanation of user settings in the ACP. + - [Feature] A function for reading metadata (`composer.json`) has been added to the Common class. + - [Feature] Added switch in load settings to disable sql request for first unread post in RTNG. + - [Feature] Added events to `rtng_body_site`. + - [Feature] Added events to `rtng_body_topbottom`. + - [Feature] Added canonical link to separate page. + - [Feature] Added vars in event `modify_tpl_ary`. `$disp_topic_title` and properties of the first unread post to `$row`. + - [Fixed] Pagination generates an incorrect list if the start value is outside the range. + - [Fixed] Message `RTNG_NO_TOPICS` don't display on index. + - [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/docs/Events.md b/imcger/recenttopicsng/docs/Events.md index da4b163..b0096d5 100644 --- a/imcger/recenttopicsng/docs/Events.md +++ b/imcger/recenttopicsng/docs/Events.md @@ -14,11 +14,13 @@ ### `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 -* Since: 1.0.0 +* Since: 1.0.0 +* Changed: 1.1.0 Variables added. $disp_topic_title and properties of the first unread post in $row * known listeners: / * Arguments: - - @var array row Array with topic data - - @var array tpl_ary Template block array with topic data + - @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 @@ -79,3 +81,71 @@ + \ext\imcger\recenttopicsng\styles\all\template\rtng_body_topbottom.html * Purpose: Append information to last post author username of member * Since: 1.0.0 + +### `forumlist_body_category_header_before` +* Location: + + \ext\imcger\recenttopicsng\styles\all\template\rtng_body_topbottom.html +* Purpose: Add content before the header of the category on the forum list. +* Since: 1.1.0 + +### `forumlist_body_category_header_row_prepend` +* Location: + + \ext\imcger\recenttopicsng\styles\all\template\rtng_body_side.html + + \ext\imcger\recenttopicsng\styles\all\template\rtng_body_topbottom.html +* Purpose: Add content before the header row of the category on the forum list. +* Since: 1.1.0 + +### `forumlist_body_category_header_row_append` +* Location: + + \ext\imcger\recenttopicsng\styles\all\template\rtng_body_side.html + + \ext\imcger\recenttopicsng\styles\all\template\rtng_body_topbottom.html +* Purpose: Add content after the header row of the category on the forum list. +* Since: 1.1.0 + +### `viewforum_body_topicrow_row_before` +* Location: + + \ext\imcger\recenttopicsng\styles\all\template\rtng_body_topbottom.html +* Purpose: Add content before list of topics. +* Since: 1.1.0 + +### `viewforum_body_topic_row_prepend` +* Location: + + \ext\imcger\recenttopicsng\styles\all\template\rtng_body_topbottom.html +* Purpose: Add content at the end of the topic list item. +* Since: 1.1.0 + +### `topiclist_row_topic_title_after` +* Location: + + \ext\imcger\recenttopicsng\styles\all\template\rtng_body_topbottom.html +* Purpose: Add content into topic rows (after the elements containing the topic titles) +* Since: 1.1.0 + +### `topiclist_row_topic_by_author_after` +* Location: + + \ext\imcger\recenttopicsng\styles\all\template\rtng_body_topbottom.html +* Purpose: Add content into topic rows (after the "by topic author" row) +* Since: 1.1.0 + +### `topiclist_row_prepend` +* Location: + + \ext\imcger\recenttopicsng\styles\all\template\rtng_body_topbottom.html +* Purpose: Add content into topic rows (inside the elements containing topic titles) +* Since: 1.1.0 + +### `topiclist_row_topic_by_author_before` +* Location: + + \ext\imcger\recenttopicsng\styles\all\template\rtng_body_topbottom.html +* Purpose: Add content into topic rows (before the "by topic author" row) +* Since: 1.1.0 + +### `viewforum_body_topic_row_append` +* Location: + + \ext\imcger\recenttopicsng\styles\all\template\rtng_body_topbottom.html +* Purpose: Add content at the start of the topic list item. +* Since: 1.1.0 + +### `viewforum_body_topic_row_after` +* Location: + + \ext\imcger\recenttopicsng\styles\all\template\rtng_body_topbottom.html +* Purpose: Add content after the topic list item. +* Since: 1.1.0 diff --git a/imcger/recenttopicsng/event/acp_listener.php b/imcger/recenttopicsng/event/acp_listener.php index a82c68d..7dabf7b 100644 --- a/imcger/recenttopicsng/event/acp_listener.php +++ b/imcger/recenttopicsng/event/acp_listener.php @@ -17,20 +17,13 @@ class acp_listener implements EventSubscriberInterface { - protected object $template; - protected object $request; - protected object $ctrl_common; - public function __construct ( - \phpbb\template\template $template, - \phpbb\request\request $request, - \imcger\recenttopicsng\controller\controller_common $controller_common + protected \phpbb\template\template $template, + protected \phpbb\request\request $request, + protected \imcger\recenttopicsng\controller\controller_common $ctrl_common, ) { - $this->template = $template; - $this->request = $request; - $this->ctrl_common = $controller_common; } public static function getSubscribedEvents(): array @@ -42,6 +35,7 @@ public static function getSubscribedEvents(): array 'core.acp_users_prefs_modify_data' => 'acp_users_prefs_modify_data', 'core.acp_users_prefs_modify_sql' => 'acp_users_prefs_modify_sql', 'core.acp_users_prefs_modify_template_data' => 'acp_users_prefs_modify_template_data', + 'core.acp_board_config_edit_add' => 'acp_board_config_edit_add', ]; } @@ -136,4 +130,22 @@ public function acp_users_prefs_modify_template_data(object $event): void $event['user_prefs_data'] = array_merge($event['user_prefs_data'], $template_vars); } } + + /** + * Event to add and/or modify acp_board configurations + */ + public function acp_board_config_edit_add(object $event): void + { + $display_vars = $event['display_vars']; + if (isset($display_vars['title']) && $display_vars['title'] == 'ACP_LOAD_SETTINGS') + { + $rtng_vars = [ + 'rtng_options_legend' => 'RTNG_LOAD_OPTIONS', + 'rtng_load_first_unrd_post' => ['lang' => 'RTNG_LOAD_FIRST_UNRD_POST', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true], + ]; + + $display_vars['vars'] = phpbb_insert_config_array($display_vars['vars'], $rtng_vars, ['before' => 'legend3']); + $event['display_vars'] = $display_vars; + } + } } diff --git a/imcger/recenttopicsng/event/main_listener.php b/imcger/recenttopicsng/event/main_listener.php index 6884711..588eb03 100644 --- a/imcger/recenttopicsng/event/main_listener.php +++ b/imcger/recenttopicsng/event/main_listener.php @@ -17,31 +17,19 @@ class main_listener implements EventSubscriberInterface { - protected object $rtng_functions; - protected object $template; - protected object $helper; - protected object $language; - protected object $auth; - protected object $ctrl_common; private array $user_setting; public function __construct ( - \imcger\recenttopicsng\core\rtng_functions $rtng_functions, - \phpbb\template\template $template, - \phpbb\controller\helper $helper, - \phpbb\language\language $language, - \phpbb\auth\auth $auth, - \imcger\recenttopicsng\controller\controller_common $controller_common + protected \imcger\recenttopicsng\core\rtng_functions $rtng_functions, + protected \phpbb\template\template $template, + protected \phpbb\controller\helper $helper, + protected \phpbb\language\language $language, + protected \phpbb\auth\auth $auth, + protected \imcger\recenttopicsng\controller\controller_common $ctrl_common, + private \phpbb\collapsiblecategories\operator\operator|null $collapsable_categories = null, ) { - $this->rtng_functions = $rtng_functions; - $this->template = $template; - $this->helper = $helper; - $this->language = $language; - $this->auth = $auth; - $this->ctrl_common = $controller_common; - $this->user_setting = $this->ctrl_common->get_user_setting(); } @@ -53,6 +41,7 @@ public static function getSubscribedEvents(): array 'core.index_modify_page_title' => 'display_rt', 'core.permissions' => 'add_permission', 'core.viewonline_overwrite_location' => 'viewonline_overwrite_location', + 'core.display_forums_before' => 'display_forums_before', ]; } @@ -61,11 +50,28 @@ public function user_setup_after(): void $this->language->add_lang('rtng_common', 'imcger/recenttopicsng'); } + public function display_forums_before(): void + { + // support for phpbb collapsable categories extension + if (isset($this->collapsable_categories)) + { + $rtng_cc = []; + $fid = 'fid_rtng'; // can be any unique string to identify the collapsible element of your extension. + $rtng_cc[] = [ + 'S_FORUM_HIDDEN' => $this->collapsable_categories->is_collapsed($fid), + 'U_COLLAPSE_URL' => $this->collapsable_categories->get_collapsible_link($fid), + ]; + + $this->template->assign_vars(['rtng_cc' => $rtng_cc]); + } + } + public function set_template_vars(): void { $this->template->assign_vars([ 'U_RTNG_PAGE_SEPARATE' => $this->helper->route('imcger_recenttopicsng_page_controller', ['page' => 'separate']), 'S_RTNG_LINK_IN_NAVBAR' => $this->auth->acl_get('u_rtng_view') && $this->user_setting['user_rtng_enable'] && $this->user_setting['user_rtng_location'] == 'RTNG_SEPARATE', + 'RTNG_TITLE_DYN' => $this->language->lang('RTNG' . ($this->user_setting['user_rtng_unread_only'] ? '_UNREAD' : '') . '_TITLE'), ]); } @@ -106,8 +112,10 @@ public function viewonline_overwrite_location(object $event): void { $session_page_parts = explode('/', $event['row']['session_page']); $site = end($session_page_parts); + $user_setting = $this->ctrl_common->get_user_setting($event['row']['user_id']); + $title = $this->language->lang('RTNG' . ($user_setting['user_rtng_unread_only'] ? '_UNREAD' : '') . '_TITLE'); - $event['location'] = $this->language->lang('RTNG_READ_' . strtoupper($site)); + $event['location'] = $this->language->lang('RTNG_READ_' . strtoupper($site), $title); $event['location_url'] = $this->helper->route('imcger_recenttopicsng_page_controller', ['page' => $site]); } } diff --git a/imcger/recenttopicsng/event/ucp_listener.php b/imcger/recenttopicsng/event/ucp_listener.php index 71f40df..252da9c 100644 --- a/imcger/recenttopicsng/event/ucp_listener.php +++ b/imcger/recenttopicsng/event/ucp_listener.php @@ -17,32 +17,17 @@ class ucp_listener implements EventSubscriberInterface { - protected object $auth; - protected object $request; - protected object $template; - protected object $user; - protected object $language; - protected object $db; - protected object $ctrl_common; - public function __construct ( - \phpbb\auth\auth $auth, - \phpbb\request\request $request, - \phpbb\template\template $template, - \phpbb\user $user, - \phpbb\language\language $language, - \phpbb\db\driver\driver_interface $db, - \imcger\recenttopicsng\controller\controller_common $controller_common + protected \phpbb\auth\auth $auth, + protected \phpbb\request\request $request, + protected \phpbb\template\template $template, + protected \phpbb\user $user, + protected \phpbb\language\language $language, + protected \phpbb\db\driver\driver_interface $db, + protected \imcger\recenttopicsng\controller\controller_common $ctrl_common, ) { - $this->auth = $auth; - $this->request = $request; - $this->template = $template; - $this->user = $user; - $this->language = $language; - $this->db = $db; - $this->ctrl_common = $controller_common; } public static function getSubscribedEvents(): array @@ -115,7 +100,7 @@ public function ucp_prefs_set_data(object $event): void public function ucp_register_set_data(object $event): void { // Read guest account settings as default - $user_data = $this->ctrl_common->get_rtng_user_data(); + $user_data = $this->ctrl_common->get_rtng_user_data(ANONYMOUS); $sql = 'UPDATE ' . USERS_TABLE . ' SET ' . $this->db->sql_build_array('UPDATE', $user_data) . ' diff --git a/imcger/recenttopicsng/ext.php b/imcger/recenttopicsng/ext.php index 156a925..2ebc20f 100644 --- a/imcger/recenttopicsng/ext.php +++ b/imcger/recenttopicsng/ext.php @@ -18,7 +18,7 @@ class ext extends \phpbb\extension\base public function is_enableable() { $valid_phpbb = phpbb_version_compare(PHPBB_VERSION, '3.3.5', '>=') && phpbb_version_compare(PHPBB_VERSION, '3.4.0-dev', '<'); - $valid_php = phpbb_version_compare(PHP_VERSION, '7.4.0', '>=') && phpbb_version_compare(PHP_VERSION, '8.5.0-dev', '<'); + $valid_php = phpbb_version_compare(PHP_VERSION, '8.0.0', '>=') && phpbb_version_compare(PHP_VERSION, '8.6.0-dev', '<'); return ($valid_phpbb && $valid_php); } diff --git a/imcger/recenttopicsng/language/de/info_acp_rtng.php b/imcger/recenttopicsng/language/de/info_acp_rtng.php index 8827a42..7de1a31 100644 --- a/imcger/recenttopicsng/language/de/info_acp_rtng.php +++ b/imcger/recenttopicsng/language/de/info_acp_rtng.php @@ -41,20 +41,26 @@ $lang = array_merge($lang, [ // Language pack author 'RTNG_LANG_DESC' => 'Deutsch (Du)', - 'RTNG_LANG_EXT_VER' => '1.0.0', + 'RTNG_LANG_VER' => '1.1.0', 'RTNG_LANG_AUTHOR' => 'IMC-GER / LukeWCS', - //forum acp + // ACP forums 'RTNG_FORUMS' => 'In „Recent Topics NG“ anzeigen', 'RTNG_FORUMS_EXPLAIN' => 'Aktiviere dieses Kontrollkästchen, um Themen dieses Forum in den Aktuelle Themen anzuzeigen.', - //acp title - 'RTNG_NAME' => 'Recent Topics NG', // Please do not translate the name of the extension - 'RTNG_DESIG' => 'Aktuelle Themen', - 'RTNG_EXPLAIN' => 'Auf dieser Seite kannst du die Einstellungen der Erweiterung „Recent Topics NG“ anpassen.

Spezifische Foren können eingeschlossen oder ausgeschlossen werden.
Überprüfe auch die Benutzerberechtigungen, welche Benutzern erlauben, einige der Parameter für sich selbst zu verändern. Diese haben dann Vorrang vor den Einstellungen des Admin-Panels.', + // ACP nav + 'RTNG_NAME' => 'Aktuelle Themen', 'RTNG_CONFIG' => 'Einstellungen', - //allgemeine Einstellungen + // ACP module + 'RTNG_EXPLAIN' => 'Auf dieser Seite kannst du die Einstellungen der Erweiterung „%s“ anpassen.

Spezifische Foren können eingeschlossen oder ausgeschlossen werden.
Überprüfe auch die Benutzerberechtigungen, welche Benutzern erlauben, einige der Parameter für sich selbst zu verändern. Diese haben dann Vorrang vor den Einstellungen des Admin-Panels.', + + // ACP load + 'RTNG_LOAD_OPTIONS' => '„Recent Topics NG“ Optionen', + 'RTNG_LOAD_FIRST_UNRD_POST' => 'Ermöglicht den Zugriff auf den ersten ungelesenen Beitrag', + 'RTNG_LOAD_FIRST_UNRD_POST_EXPLAIN' => 'Wenn diese Option aktiviert ist, werden die Daten des ersten ungelesenen Beitrags ausgelesen und zur weiteren Verarbeitung bereitgestellt.
Serverseitige Gelesen-Markierung aktivieren“ muss aktiviert sein.', + + // Global settings 'RTNG_GLOBAL_SETTINGS' => 'Globale Einstellungen', 'RTNG_INDEX_DISPLAY_EXP' => 'Anzeigen auf der Index-Seite.', 'RTNG_ALL_TOPICS' => 'Alle Seiten anzeigen', @@ -71,8 +77,9 @@ 'RTNG_SIMPLE_PAGE_QTY' => 'Anzahl der Seiten in der vereinfachten Anzeige', 'RTNG_SIMPLE_PAGE_QTY_EXP' => 'Damit kannst du für die vereinfachte Anzeige festlegen, wie viele Listen-Seiten maximal angezeigt werden sollen.', - //Benutzereinstellungen + // User Overridable settings. these apply for anon users and can be overridden by UCP 'RTNG_OVERRIDABLE' => 'Einstellungen, die im Benutzerkontrollzentrum geändert werden können', + 'RTNG_OVERRIDABLE_EXPLAIN' => 'Damit der Benutzer diese Einstellungen im Benutzerkontrollzentrum verändern kann, muss ihm in der Rechteverwaltung das entsprechende Benutzerrecht zugewiesen werden. Hat er dieses Recht nicht, werden für ihn diese Standardeinstellungen angewendet. Diese Werte werden auch für neue Benutzer und Gäste gesetzt.

Damit der Titel, Autor und das Beitragsdatum des ersten ungelesenen Beitrags als Anzeige im Thementitel ausgewählt werden kann, muss diese Option in den Einstellungen der Serverlast aktiviert werden.', 'RTNG_ENABLE' => 'Aktuelle Themen anzeigen', 'RTNG_LOCATION' => 'Anzeigeort', 'RTNG_LOCATION_EXP' => 'Wähle den Anzeigeort der aktuellen Themen.', diff --git a/imcger/recenttopicsng/language/de/rtng_common.php b/imcger/recenttopicsng/language/de/rtng_common.php index 7b7a1d9..52f0855 100644 --- a/imcger/recenttopicsng/language/de/rtng_common.php +++ b/imcger/recenttopicsng/language/de/rtng_common.php @@ -39,11 +39,11 @@ // ‚ ‘ ’ « » “ ” … „ “ // $lang = array_merge($lang, [ - 'RTNG_NAME' => 'Recent Topics NG', - 'RTNG_DESIG' => 'Aktuelle Themen', - 'RTNG_NO_TOPICS' => 'Es sind keine neuen Themen vorhanden.', - 'RTNG_TOPICS_COUNT' => '%d Themen', + 'RTNG_NO_TOPICS' => 'Es sind keine neuen Themen vorhanden.', + 'RTNG_TOPICS_COUNT' => '%d Themen', - 'RTNG_READ_SEPARATE' => 'Betrachtet „Aktuelle Themen“', - 'RTNG_READ_SIMPLE' => 'Betrachtet „Aktuelle Themen“ (vereinfachte Seite)', + 'RTNG_TITLE' => 'Aktuelle Themen', + 'RTNG_UNREAD_TITLE' => 'Ungelesene Themen', + 'RTNG_READ_SEPARATE' => 'Betrachtet „%s“', + 'RTNG_READ_SIMPLE' => 'Betrachtet „%s“ (vereinfachte Seite)', ]); 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 514e23c..0d61a09 100644 --- a/imcger/recenttopicsng/language/de_x_sie/info_acp_rtng.php +++ b/imcger/recenttopicsng/language/de_x_sie/info_acp_rtng.php @@ -41,20 +41,26 @@ $lang = array_merge($lang, [ // Language pack author 'RTNG_LANG_DESC' => 'Deutsch (Sie)', - 'RTNG_LANG_EXT_VER' => '1.0.0', + 'RTNG_LANG_VER' => '1.1.0', 'RTNG_LANG_AUTHOR' => 'IMC-GER / LukeWCS', - //forum acp + // ACP forums 'RTNG_FORUMS' => 'In „Recent Topics NG“ anzeigen', 'RTNG_FORUMS_EXPLAIN' => 'Aktiviere dieses Kontrollkästchen, um Themen dieses Forum in den Aktuelle Themen anzuzeigen.', - //acp title - 'RTNG_NAME' => 'Recent Topics NG', // Please do not translate the name of the extension - 'RTNG_DESIG' => 'Aktuelle Themen', - 'RTNG_EXPLAIN' => 'Auf dieser Seite können Sie die Einstellungen der Erweiterung „Recent Topics NG“ anpassen.

Spezifische Foren können eingeschlossen oder ausgeschlossen werden.
Überprüfe auch die Benutzerberechtigungen, welche Benutzern erlauben, einige der Parameter für sich selbst zu verändern. Diese haben dann Vorrang vor den Einstellungen des Admin-Panels.', + // ACP nav + 'RTNG_NAME' => 'Aktuelle Themen', 'RTNG_CONFIG' => 'Einstellungen', - //allgemeine Einstellungen + // ACP module + 'RTNG_EXPLAIN' => 'Auf dieser Seite können Sie die Einstellungen der Erweiterung „%s“ anpassen.

Spezifische Foren können eingeschlossen oder ausgeschlossen werden.
Überprüfe auch die Benutzerberechtigungen, welche Benutzern erlauben, einige der Parameter für sich selbst zu verändern. Diese haben dann Vorrang vor den Einstellungen des Admin-Panels.', + + // ACP load + 'RTNG_LOAD_OPTIONS' => '„Recent Topics NG“ Optionen', + 'RTNG_LOAD_FIRST_UNRD_POST' => 'Ermöglicht den Zugriff auf den ersten ungelesenen Beitrag', + 'RTNG_LOAD_FIRST_UNRD_POST_EXPLAIN' => 'Wenn diese Option aktiviert ist, werden die Daten des ersten ungelesenen Beitrags ausgelesen und zur weiteren Verarbeitung bereitgestellt.
Serverseitige Gelesen-Markierung aktivieren“ muss aktiviert sein.', + + // Global settings 'RTNG_GLOBAL_SETTINGS' => 'Globale Einstellungen', 'RTNG_INDEX_DISPLAY_EXP' => 'Anzeigen auf der Index-Seite.', 'RTNG_ALL_TOPICS' => 'Alle Seiten anzeigen', @@ -71,8 +77,9 @@ 'RTNG_SIMPLE_PAGE_QTY' => 'Anzahl der Seiten in der vereinfachten Anzeige', 'RTNG_SIMPLE_PAGE_QTY_EXP' => 'Damit können Sie für die vereinfachte Anzeige festlegen, wie viele Listen-Seiten maximal angezeigt werden sollen.', - //Benutzereinstellungen + // User Overridable settings. these apply for anon users and can be overridden by UCP 'RTNG_OVERRIDABLE' => 'Einstellungen, die im Benutzerkontrollzentrum geändert werden können', + 'RTNG_OVERRIDABLE_EXPLAIN' => 'Damit der Benutzer diese Einstellungen im Benutzerkontrollzentrum verändern kann, muss ihm in der Rechteverwaltung das entsprechende Benutzerrecht zugewiesen werden. Hat er dieses Recht nicht, werden für ihn diese Standardeinstellungen angewendet. Diese Werte werden auch für neue Benutzer und Gäste gesetzt.

Damit der Titel, Autor und das Beitragsdatum des ersten ungelesenen Beitrags als Anzeige im Thementitel ausgewählt werden kann, muss diese Option in den Einstellungen der Serverlast aktiviert werden.', 'RTNG_ENABLE' => 'Aktuelle Themen anzeigen', 'RTNG_LOCATION' => 'Anzeigeort', 'RTNG_LOCATION_EXP' => 'Wähle den Anzeigeort der aktuellen Themen.', diff --git a/imcger/recenttopicsng/language/de_x_sie/rtng_common.php b/imcger/recenttopicsng/language/de_x_sie/rtng_common.php index 7b7a1d9..52f0855 100644 --- a/imcger/recenttopicsng/language/de_x_sie/rtng_common.php +++ b/imcger/recenttopicsng/language/de_x_sie/rtng_common.php @@ -39,11 +39,11 @@ // ‚ ‘ ’ « » “ ” … „ “ // $lang = array_merge($lang, [ - 'RTNG_NAME' => 'Recent Topics NG', - 'RTNG_DESIG' => 'Aktuelle Themen', - 'RTNG_NO_TOPICS' => 'Es sind keine neuen Themen vorhanden.', - 'RTNG_TOPICS_COUNT' => '%d Themen', + 'RTNG_NO_TOPICS' => 'Es sind keine neuen Themen vorhanden.', + 'RTNG_TOPICS_COUNT' => '%d Themen', - 'RTNG_READ_SEPARATE' => 'Betrachtet „Aktuelle Themen“', - 'RTNG_READ_SIMPLE' => 'Betrachtet „Aktuelle Themen“ (vereinfachte Seite)', + 'RTNG_TITLE' => 'Aktuelle Themen', + 'RTNG_UNREAD_TITLE' => 'Ungelesene Themen', + 'RTNG_READ_SEPARATE' => 'Betrachtet „%s“', + 'RTNG_READ_SIMPLE' => 'Betrachtet „%s“ (vereinfachte Seite)', ]); diff --git a/imcger/recenttopicsng/language/en/info_acp_rtng.php b/imcger/recenttopicsng/language/en/info_acp_rtng.php index 7aeeab9..f1d85dd 100644 --- a/imcger/recenttopicsng/language/en/info_acp_rtng.php +++ b/imcger/recenttopicsng/language/en/info_acp_rtng.php @@ -41,20 +41,26 @@ $lang = array_merge($lang, [ // Language pack author 'RTNG_LANG_DESC' => 'English', - 'RTNG_LANG_EXT_VER' => '1.0.0', + 'RTNG_LANG_VER' => '1.1.0', 'RTNG_LANG_AUTHOR' => 'IMC-GER / LukeWCS', - //forum acp + // ACP forums 'RTNG_FORUMS' => 'Display on “Recent Topics NG”', 'RTNG_FORUMS_EXPLAIN' => 'Enable this checkbox to display topics from this forum in the list of recent topics.', - //acp title - 'RTNG_NAME' => 'Recent Topics NG', // Please do not translate the name of the extension - 'RTNG_DESIG' => 'Recent Topics', - 'RTNG_EXPLAIN' => 'On this page you can change the settings specific for the Recent Topics extension.

Specific forums can be included or excluded by editing the respective forums in your ACP.
Also be sure to check your user permissions, which allow users to change some of the settings found below for themselves.', + // ACP nav + 'RTNG_NAME' => 'Recent Topics', 'RTNG_CONFIG' => 'Configuration', - //global settings + // ACP module + 'RTNG_EXPLAIN' => 'On this page you can change the settings specific for the “%s” extension.

Specific forums can be included or excluded by editing the respective forums in your ACP.
Also be sure to check your user permissions, which allow users to change some of the settings found below for themselves.', + + // ACP load + 'RTNG_LOAD_OPTIONS' => '“Recent Topics NG” options', + 'RTNG_LOAD_FIRST_UNRD_POST' => 'Allows access to the first unread post', + 'RTNG_LOAD_FIRST_UNRD_POST_EXPLAIN' => 'If this option is enabled, the data of the first unread post is read and made available for further processing.
Enable server-side topic marking” must be enabled.', + + // Global settings 'RTNG_GLOBAL_SETTINGS' => 'Global Settings', 'RTNG_INDEX_DISPLAY_EXP' => 'Display on Index page', 'RTNG_ALL_TOPICS' => 'Show all recent topic pages', @@ -71,8 +77,9 @@ 'RTNG_SIMPLE_PAGE_QTY' => 'Number of pages in the simplified display', 'RTNG_SIMPLE_PAGE_QTY_EXP' => 'This allows you to specify the maximum number of list pages to be displayed for the simplified display.', - //User Overridable settings. these apply for anon users and can be overridden by UCP + // User Overridable settings. these apply for anon users and can be overridden by UCP 'RTNG_OVERRIDABLE' => 'UCP overridable Settings', + 'RTNG_OVERRIDABLE_EXPLAIN' => 'In order for the user to be able to change these settings in the user control center, the corresponding user permission must be assigned to them in the permission management. If they do not have this permission, these default settings will be applied for them. These values are also set for new users and guests.

In order for the title, author, and date of the first unread post to be selected for display in the topic title, this option must be enabled in the server load settings.', 'RTNG_ENABLE' => 'Display recent topics', 'RTNG_LOCATION' => 'Display location', 'RTNG_LOCATION_EXP' => 'Select location to display recent topics.', diff --git a/imcger/recenttopicsng/language/en/rtng_common.php b/imcger/recenttopicsng/language/en/rtng_common.php index 8069245..39d0a07 100644 --- a/imcger/recenttopicsng/language/en/rtng_common.php +++ b/imcger/recenttopicsng/language/en/rtng_common.php @@ -39,11 +39,11 @@ // ‚ ‘ ’ « » “ ” … „ “ // $lang = array_merge($lang, [ - 'RTNG_NAME' => 'Recent Topics NG', - 'RTNG_DESIG' => 'Recent Topics', - 'RTNG_NO_TOPICS' => 'There are no new topics to display.', - 'RTNG_TOPICS_COUNT' => '%d Topics', + 'RTNG_NO_TOPICS' => 'There are no new topics to display.', + 'RTNG_TOPICS_COUNT' => '%d Topics', - 'RTNG_READ_SEPARATE' => 'Reading “Recent Topics”', - 'RTNG_READ_SIMPLE' => 'Reading “Recent Topics” (simplified page)', + 'RTNG_TITLE' => 'Recent Topics', + 'RTNG_UNREAD_TITLE' => 'Unread Topics', + 'RTNG_READ_SEPARATE' => 'Reading “%s”', + 'RTNG_READ_SIMPLE' => 'Reading “%s” (simplified page)', ]); diff --git a/imcger/recenttopicsng/migrations/v_1_1_0.php b/imcger/recenttopicsng/migrations/v_1_1_0.php new file mode 100644 index 0000000..efac2b8 --- /dev/null +++ b/imcger/recenttopicsng/migrations/v_1_1_0.php @@ -0,0 +1,52 @@ +config['rtng_load_first_unrd_post']); + } + + public static function depends_on(): array + { + return ['\imcger\recenttopicsng\migrations\v_1_0_0']; + } + + public function update_data(): array + { + return [ + // Add new config vars + ['config.add', ['rtng_load_first_unrd_post', 0]], + + // Set rtng_load_first_unrd_post to true when + // user_rtng_disp_first_unrd_post is set in one or more columm + ['custom', [[$this, 'isset_first_unrd_post']]], + ]; + } + + public function isset_first_unrd_post() + { + $sql = 'SELECT COUNT(*) AS unrd_post + FROM ' . USERS_TABLE . ' + WHERE user_rtng_disp_first_unrd_post = 1'; + + $result = $this->db->sql_query($sql); + $unrd_post = $this->db->sql_fetchfield('unrd_post'); + $this->db->sql_freeresult($result); + + $this->config->set('rtng_load_first_unrd_post', (bool) $unrd_post); + } +} diff --git a/imcger/recenttopicsng/styles/all/template/event/index_body_forumlist_body_after.html b/imcger/recenttopicsng/styles/all/template/event/index_body_forumlist_body_after.html index 9e4ada1..ec3fed0 100644 --- a/imcger/recenttopicsng/styles/all/template/event/index_body_forumlist_body_after.html +++ b/imcger/recenttopicsng/styles/all/template/event/index_body_forumlist_body_after.html @@ -10,7 +10,7 @@ * Based on the original NV Recent Topics by Joas Schilling (nickvergessen) #} -{% if RTNG_DISPLAY %} +{% if RTNG_TOPICS_DISPLAY %} {% if S_RTNG_LOCATION_BOTTOM %}
{% include '@imcger_recenttopicsng/rtng_body_topbottom.html' %} diff --git a/imcger/recenttopicsng/styles/all/template/event/index_body_markforums_after.html b/imcger/recenttopicsng/styles/all/template/event/index_body_markforums_after.html index cc18afb..34cc28d 100644 --- a/imcger/recenttopicsng/styles/all/template/event/index_body_markforums_after.html +++ b/imcger/recenttopicsng/styles/all/template/event/index_body_markforums_after.html @@ -10,7 +10,7 @@ * Based on the original NV Recent Topics by Joas Schilling (nickvergessen) #} -{% if RTNG_DISPLAY %} +{% if RTNG_TOPICS_DISPLAY %} {% if S_RTNG_LOCATION_TOP %}
{% include '@imcger_recenttopicsng/rtng_body_topbottom.html' %} diff --git a/imcger/recenttopicsng/styles/all/template/event/overall_header_head_append.html b/imcger/recenttopicsng/styles/all/template/event/overall_header_head_append.html index d60a0ca..9139f1f 100644 --- a/imcger/recenttopicsng/styles/all/template/event/overall_header_head_append.html +++ b/imcger/recenttopicsng/styles/all/template/event/overall_header_head_append.html @@ -10,7 +10,7 @@ * Based on the original NV Recent Topics by Joas Schilling (nickvergessen) #} -{% if RTNG_DISPLAY %} +{% if RTNG_TOPICS_DISPLAY %} {% INCLUDEJS '@imcger_recenttopicsng/recenttopicsng.js' %} {% INCLUDECSS '@imcger_recenttopicsng/recenttopicsng.css' %} {% endif %} diff --git a/imcger/recenttopicsng/styles/all/template/event/overall_header_navigation_append.html b/imcger/recenttopicsng/styles/all/template/event/overall_header_navigation_append.html index dd3eb78..c4a442e 100644 --- a/imcger/recenttopicsng/styles/all/template/event/overall_header_navigation_append.html +++ b/imcger/recenttopicsng/styles/all/template/event/overall_header_navigation_append.html @@ -12,8 +12,8 @@ {% if S_RTNG_LINK_IN_NAVBAR %}
  • - - {{ lang('RTNG_DESIG') }} + + {{ RTNG_TITLE_DYN }}
  • {% endif %} diff --git a/imcger/recenttopicsng/styles/all/template/rtng_body_separate.html b/imcger/recenttopicsng/styles/all/template/rtng_body_separate.html index bc8db21..5835b1c 100644 --- a/imcger/recenttopicsng/styles/all/template/rtng_body_separate.html +++ b/imcger/recenttopicsng/styles/all/template/rtng_body_separate.html @@ -13,7 +13,7 @@ {% include 'overall_header.html' %} {% EVENT viewforum_forum_title_before %} -

    {{ lang('RTNG_DESIG') }}

    +

    {{ RTNG_TITLE_DYN }}

    {% EVENT viewforum_forum_title_after %} {% EVENT viewforum_body_topic_row_before %} {% set S_RTNG_LOCATION_TOP = true %} diff --git a/imcger/recenttopicsng/styles/all/template/rtng_body_side.html b/imcger/recenttopicsng/styles/all/template/rtng_body_side.html index ee2a960..0411c06 100644 --- a/imcger/recenttopicsng/styles/all/template/rtng_body_side.html +++ b/imcger/recenttopicsng/styles/all/template/rtng_body_side.html @@ -11,121 +11,125 @@ #} {% if S_RTNG_LOCATION_SIDE %} - -
    -
    -
      -
    • -
      -
      - {{ lang('RTNG_DESIG') }} -
      -
      -
      - {% set S_CC_FORUM_HIDDEN = S_EXT_COLCAT_HIDDEN %} - {% set U_CC_COLLAPSE_URL = U_EXT_COLCAT_COLLAPSE_URL %} - {% include '@phpbb_collapsiblecategories/collapsible_categories_button.html' ignore missing %} -
    • -
    -
    -
    - -{% for rtng in loops.rtng %} - {% if !rtng.S_TOPIC_TYPE_SWITCH && !rtng.S_FIRST_ROW %} - - {% endif %} +
    +
    +
      +
    • + {% EVENT forumlist_body_category_header_row_prepend %} +
      +
      + {{ RTNG_TITLE_DYN }} +
      +
      +
      + {# Loop is for better compatibility with Collapse Category, runs only one time -#} + {%- for forumrow in rtng_cc -%} + {% EVENT forumlist_body_category_header_row_append %} + {%- else -%} + {% EVENT forumlist_body_category_header_row_append %} + {%- endfor %} +
    • +
    +
    +
    + {% for rtng in rtng_topics %} + {% if !rtng.S_TOPIC_TYPE_SWITCH && !loop.first %} + + {% endif %} - {% if rtng.S_FIRST_ROW || !rtng.S_TOPIC_TYPE_SWITCH %} -
      - {% endif %} -
    • + {% if loop.first || !rtng.S_TOPIC_TYPE_SWITCH %} +
        + {% endif %} -
        - - {% if rtng.S_UNREAD_TOPIC && !S_IS_BOT %}{% endif %} -
        - {% EVENT topiclist_row_prepend %} - - {% if rtng.S_DISP_FIRST_UNREAD_POST %} - {{ rtng.FIRST_UNREAD_POST_SUBJECT }} - {% else %} - {{ rtng.S_DISP_LAST_POST ? rtng.LAST_POST_SUBJECT : rtng.TOPIC_TITLE }} - {% endif %} - - - {% EVENT topiclist_row_append %} -
        - - {% if !S_IS_BOT %} -
        - - {{ lang('POST_BY_AUTHOR') }} {% EVENT viewforum_body_last_post_author_username_prepend %} - {% if rtng.S_DISP_FIRST_UNREAD_POST %} - {{ rtng.FIRST_UNREAD_POST_AUTHOR_FULL }} - {% else %} - {{ rtng.S_DISP_LAST_POST ? rtng.LAST_POST_AUTHOR_FULL : rtng.TOPIC_AUTHOR_FULL }} - {% endif %} - {% EVENT viewforum_body_last_post_author_username_append %} « - {% if rtng.S_DISP_FIRST_UNREAD_POST %} - {{ rtng.FIRST_UNREAD_POST_TIME }} - {% else %} - {{ rtng.S_DISP_LAST_POST ? rtng.LAST_POST_TIME : rtng.FIRST_POST_TIME }} - {% endif %} - - - {{ VIEW_LATEST_POST }} - - -
        - {% endif %} -
        - {% if rtng.S_TOPIC_UNAPPROVED || rtng.S_POSTS_UNAPPROVED %} - - {% endif %} - {% if rtng.S_TOPIC_DELETED %}{% endif %} - {% if rtng.S_TOPIC_REPORTED %}{% endif %}
        - {% if rtng.ATTACH_ICON_IMG %}{% endif %} -
        + {% if rtng.S_TOPIC_DELETED %}{% endif %} + {% if rtng.S_TOPIC_REPORTED %}{% endif %}
        + {% if rtng.ATTACH_ICON_IMG %}{% endif %} + -
        - - {% if rtng.S_LAST_ROW %} -
      - {% endif %} -{% else %} -
      -
      - {{ lang('RTNG_NO_TOPICS') }} + +
    • + {% if loop.last %} +
    + {% endif %} + {% else %} +
    +
    + {{ lang('RTNG_NO_TOPICS') }} +
    +
    + {% endfor %}
    -{% endfor %} - -
    -
    -{% if loops.pagination|length %} -
    - -
    -{% endif %} - + {% if pagination is defined %} +
    + +
    + {% endif %} {% endif %} diff --git a/imcger/recenttopicsng/styles/all/template/rtng_body_topbottom.html b/imcger/recenttopicsng/styles/all/template/rtng_body_topbottom.html index be6b4a6..3294ef0 100644 --- a/imcger/recenttopicsng/styles/all/template/rtng_body_topbottom.html +++ b/imcger/recenttopicsng/styles/all/template/rtng_body_topbottom.html @@ -11,158 +11,198 @@ #} {% if S_RTNG_LOCATION_BOTTOM || S_RTNG_LOCATION_TOP -%} + {% if pagination is defined && S_RTNG_LOCATION_TOP %} +
    + +
    + {% endif %} -{% if loops.pagination|length && (S_RTNG_LOCATION_TOP) %} -
    - -
    -{% endif %} - -{% for rtng in loops.rtng %} -{% if !rtng.S_TOPIC_TYPE_SWITCH && !rtng.S_FIRST_ROW %} - -
    -
    -{% endif %} + {% for rtng in rtng_topics %} + {% if !rtng.S_TOPIC_TYPE_SWITCH && !loop.first %} + + + + {% endif %} -{% if rtng.S_FIRST_ROW || !rtng.S_TOPIC_TYPE_SWITCH %} - -
    -
    -
      -
    • -
      -
      -
      -
      {{ lang('REPLIES') }}
      -
      {{ lang('VIEWS') }}
      -
      {{ lang('LAST_POST') }}
      -
      - {% set S_CC_FORUM_HIDDEN = S_EXT_COLCAT_HIDDEN %} - {% set U_CC_COLLAPSE_URL = U_EXT_COLCAT_COLLAPSE_URL %} - {% include '@phpbb_collapsiblecategories/collapsible_categories_button.html' ignore missing %} -
    • -
    -
      - {% endif %} -
    • + {% if loop.first || !rtng.S_TOPIC_TYPE_SWITCH %} + {% EVENT forumlist_body_category_header_before %} +
      +
      +
        +
      • + {% EVENT forumlist_body_category_header_row_prepend %} +
        +
        +
        +
        {{ lang('REPLIES') }}
        +
        {{ lang('VIEWS') }}
        +
        {{ lang('LAST_POST') }}
        +
        -
        - + {# Loop is for better compatibility with Collapse Category, runs only one time -#} + {%- for forumrow in rtng_cc -%} + {% EVENT forumlist_body_category_header_row_append %} + {%- else -%} + {% EVENT forumlist_body_category_header_row_append %} + {%- endfor %} +
      • +
      +
        + {% endif %} + {% EVENT viewforum_body_topicrow_row_before %} +
      • + {% EVENT viewforum_body_topic_row_prepend %} +
        +
        {% if rtng.S_UNREAD_TOPIC && !S_IS_BOT %}{% endif %}
        {% EVENT topiclist_row_prepend %} {% if rtng.S_UNREAD_TOPIC && !S_IS_BOT %} - - - {% endif %} + + + {% endif %} + - {% if rtng.S_DISP_FIRST_UNREAD_POST %} + {%- if rtng.S_DISP_FIRST_UNREAD_POST -%} {{ rtng.FIRST_UNREAD_POST_SUBJECT }} - {% else %} + {%- else -%} {{ rtng.S_DISP_LAST_POST ? rtng.LAST_POST_SUBJECT : rtng.TOPIC_TITLE }} - {% endif %} + {%- endif -%} {% if rtng.ATTACH_ICON_IMG %}{% endif %} {% if rtng.S_TOPIC_UNAPPROVED || rtng.S_POSTS_UNAPPROVED %} - + {% endif %} {% if rtng.S_TOPIC_DELETED %} {% endif %} {% if rtng.S_TOPIC_REPORTED %}{% endif %}
        - + {% EVENT topiclist_row_topic_title_after %} {% if !S_IS_BOT %} - - {% if rtng.REPLIES %}{% endif %} + + {% if rtng.REPLIES %}{% endif %} {% endif %} - {% if rtng.pagination|length %} - + {% if rtng.pagination is defined %} + {% endif %} - + {% EVENT topiclist_row_prepend %}
        {% if rtng.S_HAS_POLL %}{% endif %} + {% EVENT topiclist_row_topic_by_author_before %} {{ lang('POST_BY_AUTHOR') }} {% EVENT viewforum_body_topic_author_username_prepend %} - {% if rtng.S_DISP_FIRST_UNREAD_POST %} - {{ rtng.FIRST_UNREAD_POST_AUTHOR_FULL }} - {% else %} - {{ rtng.S_DISP_LAST_POST ? rtng.LAST_POST_AUTHOR_FULL : rtng.TOPIC_AUTHOR_FULL }} - {% endif %} + {% if rtng.S_DISP_FIRST_UNREAD_POST %} + {{ rtng.FIRST_UNREAD_POST_AUTHOR_FULL }} + {% else %} + {{ rtng.S_DISP_LAST_POST ? rtng.LAST_POST_AUTHOR_FULL : rtng.TOPIC_AUTHOR_FULL }} + {% endif %} {% EVENT viewforum_body_topic_author_username_append %} » - {% if rtng.S_DISP_FIRST_UNREAD_POST %} - {{ rtng.FIRST_UNREAD_POST_TIME }} - {% else %} - {{ rtng.S_DISP_LAST_POST ? rtng.LAST_POST_TIME : rtng.FIRST_POST_TIME }} - {% endif %} + {% if rtng.S_DISP_FIRST_UNREAD_POST %} + {{ rtng.FIRST_UNREAD_POST_TIME }} + {% else %} + {{ rtng.S_DISP_LAST_POST ? rtng.LAST_POST_TIME : rtng.FIRST_POST_TIME }} + {% endif %} {% if rtng.S_POST_GLOBAL && FORUM_ID != rtng.FORUM_ID %} » {{ lang('IN') }} {{ rtng.FORUM_NAME }} - {% elseif rtng.U_VIEW_FORUM && rtng.FORUM_NAME %} » {{ lang('IN') }} {% for parent_forums in rtng.parent_forums %}{{ parent_forums.FORUM_NAME }} » {% endfor %}{{ rtng.FORUM_NAME }}{% endif %} + {% elseif rtng.U_VIEW_FORUM && rtng.FORUM_NAME %} » {{ lang('IN') }} + {% for parent_forums in rtng.parent_forums %} + {{ parent_forums.FORUM_NAME }} » + {% endfor %} + {{ rtng.FORUM_NAME }} + {% endif %}
        - {% EVENT topiclist_row_append %}
        -
        -
        {{ rtng.REPLIES }} {{ lang('REPLIES') }}
        -
        {{ rtng.VIEWS }} {{ lang('VIEWS') }}
        -
        - - {{ lang('LAST_POST') }} {{ lang('POST_BY_AUTHOR') }} {% EVENT viewforum_body_last_post_author_username_prepend %} {{ rtng.LAST_POST_AUTHOR_FULL }} {% EVENT viewforum_body_last_post_author_username_append %} - {% if !S_IS_BOT %} - - - {{ VIEW_LATEST_POST }} - {% endif %}
        {{ rtng.LAST_POST_TIME }} -
        -
        -
        -
      • - {% if rtng.S_LAST_ROW %} -
      -
      -
      -{% endif %} + +
      {{ rtng.REPLIES }} {{ lang('REPLIES') }}
      +
      {{ rtng.VIEWS }} {{ lang('VIEWS') }}
      +
      -{% else %} -
      -
      - {{ lang('RTNG_NO_TOPICS') }} -
      -
      -{% endfor %} - -{% if loops.pagination|length && (S_RTNG_LOCATION_BOTTOM) %} -
      - -
      -{% endif %} + {{ lang('LAST_POST') }} {{ lang('POST_BY_AUTHOR') }} {% EVENT viewforum_body_last_post_author_username_prepend %} {{ rtng.LAST_POST_AUTHOR_FULL }} {% EVENT viewforum_body_last_post_author_username_append %} + {% if !S_IS_BOT %} + + + {{ VIEW_LATEST_POST }} + {% endif %}
      {{ rtng.LAST_POST_TIME }} +
      +
      + + {% EVENT viewforum_body_topic_row_append %} +
    • + {% EVENT viewforum_body_topic_row_after %} + {% if loop.last %} +
    +
    +
    + {% endif %} + {% else %} + {% EVENT forumlist_body_category_header_before %} +
    +
    +
      +
    • + {% EVENT forumlist_body_category_header_row_prepend %} +
      +
      +
      +
      {{ lang('REPLIES') }}
      +
      {{ lang('VIEWS') }}
      +
      {{ lang('LAST_POST') }}
      +
      + {# Loop is for better compatibility with Collapse Category, runs only one time -#} + {%- for forumrow in rtng_cc -%} + {% EVENT forumlist_body_category_header_row_append %} + {%- else -%} + {% EVENT forumlist_body_category_header_row_append %} + {%- endfor %} +
    • +
    +
    +
    + {{ lang('RTNG_NO_TOPICS') }} +
    +
    +
    +
    + {% endfor %} + {% if pagination is defined && S_RTNG_LOCATION_BOTTOM %} +
    + +
    + {% endif %} {% endif %} diff --git a/imcger/recenttopicsng/styles/all/template/rtng_macros.html b/imcger/recenttopicsng/styles/all/template/rtng_macros.html index 9b9cae0..ba6677b 100644 --- a/imcger/recenttopicsng/styles/all/template/rtng_macros.html +++ b/imcger/recenttopicsng/styles/all/template/rtng_macros.html @@ -39,7 +39,7 @@ (max !== null ? ' max="' ~ max ~ '"') ~ (step !== null ? ' step="' ~ step ~ '"') ~ (placeholder !== null ? ' placeholder="' ~ placeholder ~ '"') - }}> + }} required> {%- endmacro %} {% macro text(name, value, size = null, placeholder = null, pattern = null) -%} diff --git a/imcger/recenttopicsng/styles/all/theme/recenttopicsng.css b/imcger/recenttopicsng/styles/all/theme/recenttopicsng.css index 05c6009..9a9a53e 100644 --- a/imcger/recenttopicsng/styles/all/theme/recenttopicsng.css +++ b/imcger/recenttopicsng/styles/all/theme/recenttopicsng.css @@ -29,6 +29,22 @@ } } +@media only screen and (max-width: 700px) { + #rtng-box .panel { + margin-left: unset; + margin-right: unset; + } +} + +#rtng-box .panel { + margin-bottom: unset; + border-radius: unset; +} + +#rtng-side a.topictitle { + font-size: 1.32em; +} + #rtng ul { list-style: none; } @@ -64,7 +80,7 @@ #rtng a.forum-link { color: #877b69; - font-size: 10px; + font-size: 1.1em; } #rtng dd.lastpost {