From e109624ff7ba0681ded5b61a09624d8724f22c9b Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Mon, 17 Aug 2026 08:04:25 -0700 Subject: [PATCH 1/2] A little future proofing --- event/listener.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/event/listener.php b/event/listener.php index 7ee8c97..36dd54f 100644 --- a/event/listener.php +++ b/event/listener.php @@ -295,8 +295,11 @@ public function adjust_quickmod_tools($event) */ public function viewonline_ideas($event) { - if (($event['on_page'][1] === 'viewtopic' && $event['row']['session_forum_id'] == $this->config['ideas_forum_id']) || - ($event['on_page'][1] === 'app' && strrpos($event['row']['session_page'], 'app.' . $this->php_ext . '/ideas') === 0)) + $controller = $event['on_page'][1]; + $in_ideas_forum = $controller === 'viewtopic' && (int) $event['row']['session_forum_id'] === (int) $this->config['ideas_forum_id']; + $in_ideas_pages = in_array($controller, ['app', 'index'], true) && strpos($event['row']['session_page'], $controller . '.' . $this->php_ext . '/ideas') === 0; + + if ($in_ideas_forum || $in_ideas_pages) { $event['location'] = $this->language->lang('VIEWING_IDEAS'); $event['location_url'] = $this->helper->route('phpbb_ideas_index_controller'); From 85274b7843b0ec47c4b076d7cea87481dc867310 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Mon, 17 Aug 2026 14:08:17 -0700 Subject: [PATCH 2/2] Better viewonline route checking --- config/services.yml | 1 + event/listener.php | 34 ++++++++++++++++++++++++---- tests/event/listener_test.php | 42 +++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 4 deletions(-) diff --git a/config/services.yml b/config/services.yml index 8fd45fb..48305f0 100644 --- a/config/services.yml +++ b/config/services.yml @@ -11,6 +11,7 @@ services: - '@phpbb.ideas.idea' - '@language' - '@phpbb.ideas.linkhelper' + - '@router' - '@template' - '@user' - '%core.php_ext%' diff --git a/event/listener.php b/event/listener.php index 36dd54f..f600a3a 100644 --- a/event/listener.php +++ b/event/listener.php @@ -17,6 +17,7 @@ use phpbb\ideas\factory\idea; use phpbb\ideas\factory\linkhelper; use phpbb\language\language; +use phpbb\routing\router; use phpbb\template\template; use phpbb\user; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -41,6 +42,9 @@ class listener implements EventSubscriberInterface /** @var linkhelper */ protected $link_helper; + /** @var router */ + protected $router; + /** @var template */ protected $template; @@ -57,11 +61,12 @@ class listener implements EventSubscriberInterface * @param idea $idea * @param language $language * @param linkhelper $link_helper + * @param router $router * @param template $template * @param user $user * @param string $php_ext */ - public function __construct(auth $auth, config $config, helper $helper, idea $idea, language $language, linkhelper $link_helper, template $template, user $user, $php_ext) + public function __construct(auth $auth, config $config, helper $helper, idea $idea, language $language, linkhelper $link_helper, router $router, template $template, user $user, $php_ext) { $this->auth = $auth; $this->config = $config; @@ -69,6 +74,7 @@ public function __construct(auth $auth, config $config, helper $helper, idea $id $this->idea = $idea; $this->language = $language; $this->link_helper = $link_helper; + $this->router = $router; $this->template = $template; $this->user = $user; $this->php_ext = $php_ext; @@ -295,9 +301,29 @@ public function adjust_quickmod_tools($event) */ public function viewonline_ideas($event) { - $controller = $event['on_page'][1]; - $in_ideas_forum = $controller === 'viewtopic' && (int) $event['row']['session_forum_id'] === (int) $this->config['ideas_forum_id']; - $in_ideas_pages = in_array($controller, ['app', 'index'], true) && strpos($event['row']['session_page'], $controller . '.' . $this->php_ext . '/ideas') === 0; + $in_ideas_forum = $event['on_page'][1] === 'viewtopic' && (int) $event['row']['session_forum_id'] === (int) $this->config['ideas_forum_id']; + $in_ideas_pages = false; + + if (!$in_ideas_forum && isset($event['row']['session_page'])) + { + $session_path = parse_url($event['row']['session_page'], PHP_URL_PATH); + if (is_string($session_path)) + { + // Session pages include the front controller, whose name differs between + // phpBB versions. The router expects only the path that follows it. + $session_path = preg_replace('#^.*\.' . preg_quote($this->php_ext, '#') . '(?=/)#', '', $session_path); + + try + { + $route = $this->router->match($session_path); + $in_ideas_pages = strpos($route['_route'], 'phpbb_ideas_') === 0; + } + catch (\Symfony\Component\Routing\Exception\ExceptionInterface $e) + { + // Not a routed Ideas page. + } + } + } if ($in_ideas_forum || $in_ideas_pages) { diff --git a/tests/event/listener_test.php b/tests/event/listener_test.php index 37172b9..e39b00e 100644 --- a/tests/event/listener_test.php +++ b/tests/event/listener_test.php @@ -32,6 +32,9 @@ class listener_test extends \phpbb_test_case /** @var \PHPUnit\Framework\MockObject\MockObject|\phpbb\ideas\factory\linkhelper */ protected $link_helper; + /** @var \PHPUnit\Framework\MockObject\MockObject|\phpbb\routing\router */ + protected $router; + /** @var \PHPUnit\Framework\MockObject\MockObject|\phpbb\template\template */ protected $template; @@ -66,6 +69,18 @@ protected function setUp(): void $this->link_helper = $this->getMockBuilder('\phpbb\ideas\factory\linkhelper') ->disableOriginalConstructor() ->getMock(); + $this->router = $this->getMockBuilder('\phpbb\routing\router') + ->disableOriginalConstructor() + ->getMock(); + + $route_collection = new \Symfony\Component\Routing\RouteCollection(); + $route_collection->add('phpbb_ideas_index_controller', new \Symfony\Component\Routing\Route('/ideas{trailing}', array('trailing' => ''), array('trailing' => '/?'))); + $route_collection->add('phpbb_ideas_idea_controller', new \Symfony\Component\Routing\Route('/idea/{idea_id}', array(), array('idea_id' => '\\d+'))); + $route_collection->add('phpbb_ideas_list_controller', new \Symfony\Component\Routing\Route('/ideas/list/{sort}', array('sort' => 'new'))); + $route_collection->add('phpbb_ideas_post_controller', new \Symfony\Component\Routing\Route('/ideas/post')); + $matcher = new \Symfony\Component\Routing\Matcher\UrlMatcher($route_collection, new \Symfony\Component\Routing\RequestContext()); + $this->router->method('match') + ->willReturnCallback(array($matcher, 'match')); $this->template = $this->getMockBuilder('\phpbb\template\template') ->getMock(); $this->user = new \phpbb\user($this->lang, '\phpbb\datetime'); @@ -86,6 +101,7 @@ protected function get_listener() $this->idea, $this->lang, $this->link_helper, + $this->router, $this->template, $this->user, $this->php_ext @@ -387,6 +403,32 @@ public function viewonline_data() 'phpbb_ideas_index_controller#a:0:{}', 'VIEWING_IDEAS', ), + // test a parameterised Ideas route with the phpBB 4 front controller + array( + array( + 1 => 'index', + ), + array( + 'session_page' => 'index.' . $phpEx . '/ideas/list/popular?start=25' + ), + '$location_url', + '$location', + 'phpbb_ideas_index_controller#a:0:{}', + 'VIEWING_IDEAS', + ), + // test an Idea route with an arbitrary front-controller name + array( + array( + 1 => 'front', + ), + array( + 'session_page' => 'front.' . $phpEx . '/idea/42' + ), + '$location_url', + '$location', + 'phpbb_ideas_index_controller#a:0:{}', + 'VIEWING_IDEAS', + ), // test when viewing an idea topic (any topic in forum id 2) array( array(