Advanced Forum and Forum Access Incompatibility
| Project: | Forum Access |
| Version: | 6.x-1.x-dev |
| Component: | Miscellaneous |
| Category: | support request |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | active |
Jump to:
I installed Forum Access and Advanced Forum on Drupal 6.13. I noticed a bug where forum moderators were not working properly. When a forum moderator was assigned to a particular forum at admin/content/forum/edit/forum/%forumId, that moderator was able to moderate all forums, not just the one forum as intended. After hours of investigation, the issue was found to be incompatibility between the 2 modules. I believe the problem may be that both modules use the modulename_preprocess_comment function. The solution for me was to uninstall Advanced Forum, since I need the functionality of Forum Access while Advanced Forum was more a want. Hopefully this issue can be resolved because I would love to use both modules at once.

#1
I'm going to need more information to go on than that. I don't use Forum Access and AF doesn't integrate with it. There shouldn't, however, be any reason why they can't be used on the same site. If there's something that can be changed in AF to make it work without causing problems in AF, I'll happily accept a patch.
Michelle
#2
I don't know how to correctly modify the AF source code, but it looks that Forum Access add the edit/delete links on the forum comment $links. Probably AF doesn't uses the $links created by Forum Access, but it modify the default $links (which doesn't have edit/delete if the current user doesn't have "administer comments" permission).
I've modified the source code with a small workaround, I've inserted the code of _forum_access_preprocess_comment() function taken from "forum_acces.node.inc" before the end of _advanced_forum_preprocess_comment() and it works quite better: the moderator now can edit/delete comments on the forum they can moderate.
Probably a better solution could be implemented.
#3
Moreover, adding the code of _forum_access_preprocess_comment() remove the "edit" links for users which could edit theirs comments :-(
#4
AF manipulates the node/comment links quite a bit. You might be able to fix this by making sure FA runs before AF so AF uses the FA modified links. I don't use FA so I don't know what it's doing to the links. Tossing this over to the FA queue for more input.
Michelle
#5
@Michelle: thanks! I hope that FA and AF will be able to cooperate: both are extremely useful in order to have a working forum in drupal.
#6
The problem with forum_access_preprocess_comment() is that the comment links that it receives have already been themed, and I may not have all of them, because the user doesn't have the required permission.
Rather than trying to sort out what is what by back-parsing HTML and trying to create the missing ones on my own, I chose to throw them away completely, temporarily turn on the 'administer comments' permission, retrieve the comment links again (this time all of them!), remove the links that the user should not have, theme the remaining ones, and finally turn 'administer comments' back off.
Here's the function:
<?php
/**
* Recreate comment links (they've already been themed), and
* remove those that aren't accessible to the user.
*/
function _forum_access_preprocess_comment(&$variables) {
global $user;
if (!empty($user->_forum_access_moderator)) {
_forum_access_enable_moderator(); // this allows us to retrieve the comment links (without setting precedent!)
}
$tid = $variables['node']->tid;
$links = module_invoke_all('link', 'comment', $variables['comment'], 0);
if (isset($links['comment_reply']) && (!preg_match('#<li class="[^"]*comment_reply[^"]*".*</li>#U', $variables['links']) || !forum_access_access($tid, 'create'))) {
unset($links['comment_reply']);
}
if (isset($links['comment_edit']) && !forum_access_access($tid, 'update')) {
unset($links['comment_edit']);
}
if (isset($links['comment_delete']) && !forum_access_access($tid, 'delete')) {
unset($links['comment_delete']);
}
foreach(array_keys($links) as $link) {
if (!in_array($link, array('comment_reply', 'comment_edit', 'comment_delete')) && !preg_match('#<li class="[^"]*'. $link .'[^"]*".*</li>#U', $variables['links'])) {
unset($links[$link]); // eliminate possible additional unknown links that came in for 'administer_comments'
}
}
if (empty($links)) {
$links['comment_forbidden'] = array(
'title' => theme('comment_post_forbidden', $variables['node']),
'html' => TRUE,
);
}
$variables['links'] = theme('links', $links);
if (!empty($user->_forum_access_moderator) && arg(0) == 'node' && arg(2) == NULL) {
// Remove the permissions again to avoid confusing devel_node_access.module.
_forum_access_disable_moderator();
}
}
?>
This tour de force is necessary because the comment.module does not provide any hooks for manipulating the comments.
#7
Hmm... Yeah, that's quite a collision, then. I don't see any easy way to have both AF and FA links. If it's important to the functionality of FA to have the FA links, then users who have both modules installed will need to set the weight of FA in the system table to something higher than 15 so it runs last.
If someone has a better idea and writes a patch, I'll look at it but I don't use either FA or comments so this is pretty low priority for me.
Michelle
#8
What is different about AF links? Are they not delivered through
<?phpmodule_invoke_all('link', 'comment', $variables['comment'], 0);
?>
i.e. from advanced_forum_link()?
#9
AF takes the links array available in the node/comment preprocess, modifies it, and passes it back through theme_links. It does it that way because that's how I knew to do it when I started this 2 years ago in D5. I've been considering taking a look at hook_link_alter and seeing if what I do could be done there instead but it hasn't been a high priority.
Michelle
#10
Thank you for the explanation. I'll look into it, but it may take a few days...
#11
Need delete in the file advanced_forum.module this code:
if (arg(1) != 'reply') {
// Because the $links array isn't available here, we recreate it
$node = node_load($variables['comment']->nid);
$links = module_invoke_all('link', 'comment', $variables['comment']);
drupal_alter('link', $links, $node);
unset($links['comment_parent']);
// Iconify common links (optional to avoid translation issues)
_advanced_forum_buttonify_links($links);
// Remake the links with our changes
$variables['links'] = theme('links', $links, array('class' => 'links forum-links'));
$variables['links_array'] = $links;
}