[OzzModz] Force Users To Read Threads

[OzzModz] Force Users To Read Threads 2.0.9 Patch Level 2

No permission to download
@gerryvz
Quick workaround fix for the above problem. Edit "src/addons/xenMade/STFRT/Admin/Controller/FrtThread.php", replace:
Code:
Line 22:
return $this->view('xenMade\STFRT\Thread\View', 'stfrt_thread_list', $viewParams);

With:
return $this->view('xenMade\STFRT\Thread\View:View', 'stfrt_thread_list', $viewParams);
Code:
Line 74:
return $this->view('xenMade\STFRT\Thread\Delete', 'stfrt_thread_delete', $viewParams);

with:
return $this->view('xenMade\STFRT\Thread\Delete:Delete', 'stfrt_thread_delete', $viewParams);
Code:
Line 93:
return $this->view('xenMade\STFRT\Thread\Reset', 'stfrt_thread_reset', $viewParams);

with:
return $this->view('xenMade\STFRT\Thread\Reset:Reset', 'stfrt_thread_reset', $viewParams);
Code:
Line 176:
return $this->view('xenMade\STFRT\Thread\Edit', 'stfrt_thread_edit', $viewParams);

with:
return $this->view('xenMade\STFRT\Thread\Edit:Edit', 'stfrt_thread_edit', $viewParams);

Thanks for this. I figured you added the:
Code:
:View
and
Code:
:Delete

So I had to follow this for the 'FrtRead.php' file too so I was able to access the page from Admin CP. Hopefully an official patch comes soon. But this looks to be working.
 
Hello, can this plugin be made for direct messages? Most members do not read their incoming messages. It would be great if they were forced to read the messages with the plugin.
 
Ozzy, on XF 2.3.6 we still get this error even using the latest addon version:
Code:
InvalidArgumentException: Class xenMade\STFRT\Clear does not match formatter pattern %s\%s\View\%s src/XF.php:1437

Stack trace
#0 src/XF/App.php(1906): XF::stringToClass('xenMade\\STFRT\\C...', '%s\\%s\\View\\%s', 'Pub')
#1 src/XF/Container.php(233): XF\App->XF\{closure}('xenMade\\STFRT\\C...', Array, Object(XF\Container))
#2 src/XF/Container.php(246): XF\Container->create('view', 'xenMade\\STFRT\\C...', Array)
#3 src/XF/Mvc/Renderer/AbstractRenderer.php(80): XF\Container->XF\{closure}('xenMade\\STFRT\\C...', Array)
#4 src/XF/Mvc/Renderer/AbstractRenderer.php(88): XF\Mvc\Renderer\AbstractRenderer->createViewObject('xenMade\\STFRT\\C...', 'public:stfrt_us...', Array)
#5 src/XF/Mvc/Renderer/Json.php(83): XF\Mvc\Renderer\AbstractRenderer->renderViewObject('xenMade\\STFRT\\C...', 'public:stfrt_us...', Array, 'html')
#6 src/XF/Mvc/Renderer/Json.php(70): XF\Mvc\Renderer\Json->renderHtmlFallback('xenMade\\STFRT\\C...', 'public:stfrt_us...', Array)
#7 src/XF/Mvc/Dispatcher.php(471): XF\Mvc\Renderer\Json->renderView('xenMade\\STFRT\\C...', 'public:stfrt_us...', Array)
#8 src/XF/Mvc/Dispatcher.php(453): XF\Mvc\Dispatcher->renderView(Object(XF\Mvc\Renderer\Json), Object(XF\Mvc\Reply\View))
#9 src/XF/Mvc/Dispatcher.php(412): XF\Mvc\Dispatcher->renderReply(Object(XF\Mvc\Renderer\Json), Object(XF\Mvc\Reply\View))
#10 src/XF/Mvc/Dispatcher.php(66): XF\Mvc\Dispatcher->render(Object(XF\Mvc\Reply\View), 'json')
#11 src/XF/App.php(2826): XF\Mvc\Dispatcher->run()
#12 src/XF.php(806): XF\App->run()
#13 index.php(23): XF::runApp('XF\\Pub\\App')
#14 {main}
 
Ozzy, on XF 2.3.6 we still get this error even using the latest addon version:
Code:
InvalidArgumentException: Class xenMade\STFRT\Clear does not match formatter pattern %s\%s\View\%s src/XF.php:1437

Stack trace
#0 src/XF/App.php(1906): XF::stringToClass('xenMade\\STFRT\\C...', '%s\\%s\\View\\%s', 'Pub')
#1 src/XF/Container.php(233): XF\App->XF\{closure}('xenMade\\STFRT\\C...', Array, Object(XF\Container))
#2 src/XF/Container.php(246): XF\Container->create('view', 'xenMade\\STFRT\\C...', Array)
#3 src/XF/Mvc/Renderer/AbstractRenderer.php(80): XF\Container->XF\{closure}('xenMade\\STFRT\\C...', Array)
#4 src/XF/Mvc/Renderer/AbstractRenderer.php(88): XF\Mvc\Renderer\AbstractRenderer->createViewObject('xenMade\\STFRT\\C...', 'public:stfrt_us...', Array)
#5 src/XF/Mvc/Renderer/Json.php(83): XF\Mvc\Renderer\AbstractRenderer->renderViewObject('xenMade\\STFRT\\C...', 'public:stfrt_us...', Array, 'html')
#6 src/XF/Mvc/Renderer/Json.php(70): XF\Mvc\Renderer\Json->renderHtmlFallback('xenMade\\STFRT\\C...', 'public:stfrt_us...', Array)
#7 src/XF/Mvc/Dispatcher.php(471): XF\Mvc\Renderer\Json->renderView('xenMade\\STFRT\\C...', 'public:stfrt_us...', Array)
#8 src/XF/Mvc/Dispatcher.php(453): XF\Mvc\Dispatcher->renderView(Object(XF\Mvc\Renderer\Json), Object(XF\Mvc\Reply\View))
#9 src/XF/Mvc/Dispatcher.php(412): XF\Mvc\Dispatcher->renderReply(Object(XF\Mvc\Renderer\Json), Object(XF\Mvc\Reply\View))
#10 src/XF/Mvc/Dispatcher.php(66): XF\Mvc\Dispatcher->render(Object(XF\Mvc\Reply\View), 'json')
#11 src/XF/App.php(2826): XF\Mvc\Dispatcher->run()
#12 src/XF.php(806): XF\App->run()
#13 index.php(23): XF::runApp('XF\\Pub\\App')
#14 {main}
To replicate this error click on a members username > Moderator tools > Force users to read all threads again.
 
Ozzy, on XF 2.3.6 we still get this error even using the latest addon version:
Code:
InvalidArgumentException: Class xenMade\STFRT\Clear does not match formatter pattern %s\%s\View\%s src/XF.php:1437

Stack trace
#0 src/XF/App.php(1906): XF::stringToClass('xenMade\\STFRT\\C...', '%s\\%s\\View\\%s', 'Pub')
#1 src/XF/Container.php(233): XF\App->XF\{closure}('xenMade\\STFRT\\C...', Array, Object(XF\Container))
#2 src/XF/Container.php(246): XF\Container->create('view', 'xenMade\\STFRT\\C...', Array)
#3 src/XF/Mvc/Renderer/AbstractRenderer.php(80): XF\Container->XF\{closure}('xenMade\\STFRT\\C...', Array)
#4 src/XF/Mvc/Renderer/AbstractRenderer.php(88): XF\Mvc\Renderer\AbstractRenderer->createViewObject('xenMade\\STFRT\\C...', 'public:stfrt_us...', Array)
#5 src/XF/Mvc/Renderer/Json.php(83): XF\Mvc\Renderer\AbstractRenderer->renderViewObject('xenMade\\STFRT\\C...', 'public:stfrt_us...', Array, 'html')
#6 src/XF/Mvc/Renderer/Json.php(70): XF\Mvc\Renderer\Json->renderHtmlFallback('xenMade\\STFRT\\C...', 'public:stfrt_us...', Array)
#7 src/XF/Mvc/Dispatcher.php(471): XF\Mvc\Renderer\Json->renderView('xenMade\\STFRT\\C...', 'public:stfrt_us...', Array)
#8 src/XF/Mvc/Dispatcher.php(453): XF\Mvc\Dispatcher->renderView(Object(XF\Mvc\Renderer\Json), Object(XF\Mvc\Reply\View))
#9 src/XF/Mvc/Dispatcher.php(412): XF\Mvc\Dispatcher->renderReply(Object(XF\Mvc\Renderer\Json), Object(XF\Mvc\Reply\View))
#10 src/XF/Mvc/Dispatcher.php(66): XF\Mvc\Dispatcher->render(Object(XF\Mvc\Reply\View), 'json')
#11 src/XF/App.php(2826): XF\Mvc\Dispatcher->run()
#12 src/XF.php(806): XF\App->run()
#13 index.php(23): XF::runApp('XF\\Pub\\App')
#14 {main}
To replicate this error click on a members username > Moderator tools > Force users to read all threads again.
I have come to look at this addon, which was no longer maintained. I've decided to research this inside the code of the issue, as both of you have reported. It has been fixed in just 10 minutes. It was pretty quick.

1. Force Users to Read All Threads Again Fatal Error on Member Profile

File: XF/Pub/Controller/Member.php

Problem:
Clicking Moderator Tools > Force users to read all threads again on any member's profile page threw a fatal InvalidArgumentException. XenForo requires all view class identifiers to follow the pattern Vendor\Addon\App\View\Name, but the view was registered as xenMade\STFRT\Clear a two-segment string that cause fails the XenForo class resolver entirely.

Error:
Code:
InvalidArgumentException: Class xenMade\STFRT\Clear does not match formatter pattern %s\%s\View\%s

Fix:
Corrected the view class identifier to xenMade\STFRT\Pub\View\Member\FrtClear, which satisfies XenForo's naming pattern. No physical view class file is required. XenForo gracefully falls back to rendering the template directly when the class doesn't exist on disk.

2. FRT Gate Firing on All Threads, Including the Required Reading Thread Itself

Files: XF/Pub/Controller/Thread.php, XF/Pub/Controller/Post.php

Problem:
The bypass condition, intended to allow users to access the required reading thread so they could actually read it, was completely broken. The code compared $thread->node_id against $params->node_id, but thread and post routes do not carry a node_id parameter. $params->node_id always resolved to 0, meaning the condition $thread->node_id !== $params->node_id was always true, and the FRT error was thrown for every thread and post visit, with no way to ever would bypass it, including on the required reading thread itself.

Affected actions:
  • Thread::actionIndex viewing a thread
  • Thread::actionReply opening the reply form
  • Thread::actionAddReply submitting a reply
  • Post::actionQuote quoting a post

Fix:
Replaced the broken node_id parameter comparison with a correct thread_id comparison. The bypass now checks whether the thread being accessed is the actual FRT-required thread using (int)$frtThread['thread_id'] !== $thread->thread_id, which correctly allows access only to the designated reading thread.

Files Changed:

  • XF/Pub/Controller/Member.php Fixed view class name
  • XF/Pub/Controller/Thread.php Fixed bypass logic in 3 actions
  • XF/Pub/Controller/Post.php Fixed bypass logic in actionQuote
 
Back
Top Bottom