andreagdipaolo I did some tests today. Here are my observations:
I couldn't find any issue with posts (as in, replies) approval. Even if you are not allowed to see the flags you can still see the posts and approve them if you know in which discussion they are.
The problem is only with discussions. Clearly, the code in flarum/approval
intends for the same behavior to happen as with posts. The code allows any user with discussion.approvePosts
to see discussions awaiting approval.
The problem lies in the Flarum core logic that hides deleted discussions. Discussions with zero posts are only visible to the discussion author and users with editPost
permission, and this logic takes priority. Since posts under approval don't count towards the comment count, discussions under approval have a discussion count of zero and are not visible to other users, even if they have discussion.approvePosts
permission.
There's no pretty fix possible from a third-party extension, as the logic for deleted posts/discussions is encapsulated in its own subquery.
I developed this workaround that can be added to extend.php
:
<?php
class ViewApprovalDiscussionsWithoutEditAbilityWorkaround extends \Flarum\Foundation\AbstractServiceProvider
{
public function boot()
{
\Flarum\Discussion\Discussion::registerVisibilityScoper(function ($actor, $query) {
if (!$actor->hasPermission('discussion.approvePosts')) {
return;
}
foreach ($query->getQuery()->wheres as &$where) {
$query2 = \Illuminate\Support\Arr::get($where, 'query');
if (!$query2) {
continue;
}
foreach ($query2->wheres as &$where2) {
if (\Illuminate\Support\Arr::get($where2, 'column') !== 'discussions.comment_count' || \Illuminate\Support\Arr::get($where2, 'operator') !== '>') {
continue;
}
$where2['operator'] = '>=';
}
}
}, 'view');
}
}
use Flarum\Extend;
return [
// Register extenders here to customize your forum!
// [...] other existing extenders
(new Extend\ServiceProvider())
->register(ViewApprovalDiscussionsWithoutEditAbilityWorkaround::class),
];
The code essentially finds this line flarum/frameworkblob/v1.8.5/framework/core/src/Discussion/Access/ScopeDiscussionVisibility.php#L53 and replaces $query->where('discussions.comment_count', '>', 0)
with $query->where('discussions.comment_count', '>=', 0)
when the user has approvePosts
permission. The prettiest fix would be to just remove the subquery entirely but it's much more complicated to do when hacking the query.
I'm really not sure what the proper fix would be here. We would need an extender mechanism specifically for those built-in subqueries in core, so extensions can modify them reliably. Maybe a visibility-scoped subquery could work.
Another challenge is that core's visibility scopes are set at boot
, after all extensions have already added their scopes with the extender. So the only solution is to use a service provider and use the boot method to run our code after core and change the query.