HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.

How to implement a confidential category?


We recently installed Vanilla 3.3 as an intranet. Yesterday I set up another as an extranet for our staff and their customers as most are now working from home.

Private messages and conversations are just not suitable, so we need a confidential category. There was some advice in a previous discussion about setting up permissions for such a category set to personal information. This did not scale when many users a permitted to see personal information.

A seemingly simple solution was to allow users to start a discussion in the category but disable all viewing of posts in that category. The idea was users would then see responses and add comments in My Discussions. However My Discussions does not show those discussions.

Two lines of attack are:

  1. Suppress viewing of all discussions in a confidential category, all members having standard permissions so a member's own discussions in that show in My Discussions.
  2. Show members' only their own discussions in the confidential category as well as showing them in their My Discussions.

Would someone be good enough to tell me where to find the code (Views? DiscussionModel calls ?) that I would need to alter to implement one or other of these solutions as quick fix. Or a better one?

Thank you for any suggestions.



  • BleistivtBleistivt Moderator

    Why are conversations not suitable?

    Building something like this means building around permissions, which should be avoided if possible.

    If you actually want to write a plugin like that:

    The safe but complex way would be to have the category only be accessible by the staff and build a custom endpoint for viewing and posting in such a category for regular users that reflect your business logic (users can create, but only view their own discussions).

    The unsafe but easier way would be to make a regular category and throw permission errors where appropriate (user trying to view a discussion in that category that is not their own). However, this would leak discussion titles and content in many places. The API should also be considered.

  • Many thanks for your reply, Bleistivt.

    Conversations: we want to avoid PMs, mark discussions as resolved, and generally use the forum features.

    Yes, I agree about leaving permissions alone. A quick fix to introduce the business logic you aptly describe (users can create, but only view their own discussions) is to suppress display of discussions in our Advice category (id=4).. Users would go to My Discussions to view their own discussions.

    Would there be there a way to do that in short order? How could I detect that category (id=4) wants to display its discussions to a member?

  • BleistivtBleistivt Moderator

       public function categoriesController_render_before($sender) {

           if ($sender->data('Category.CategoryID') == 4) {




       public function discussionController_render_before($sender) {

           $isDiscussionCreator = $sender->data('Discussion.InsertUserID') == Gdn::session()->UserID;

           if ($sender->data('Category.CategoryID') == 4 && !$isDiscussionCreator) {




    Something like this in a plugin. This escalates the permissions to Vanilla.Comments.Editwhich only your staff should have.

    Make sure you lock down other places where the discussion content could be seen, e.g. on user profiles.

  • I will have a go at a plugin, thank you.

  • jitrjitr New
    edited March 2020

    Coming at Vanilla from a standing start writing a plugin is not so easy. Looking at class.hooks and class.discussionscontroller I am beginning to see the way ahead. However I would appreciate some advice on how to include or exclude certain categories from a list of discussions.

    To clarify, the aim is to have to have a panel like this:


    New Discussion


    My Discussions

    My Projects






    • Planning
    • Support

    Level 1 categories (News, Articles, General ...) are public open to all members. Level 2 (Planning, Support) are private to a member and staff. I am wondering how to set up a filter to include only level 1 categories in public content and level 2 in private content.

    My Discussions will show level 1 discussions while My Projects will show level 2. Search will show level 2. (My Discussions and Search could include level 1 and level 2 but I do not want to complicate things at this stage).

    In other words, a normal forum and a confidential advice channel sharing a common set of members.

    Thank you.

  • BleistivtBleistivt Moderator

    You can hook into the CategoriesModule using categoriesModule_getData_handler($sender) {...}

    And then set $sender->Data accordingly. To retrieve the category data to filter, you can just call the static CategoryModel::categories()

  • KasparKaspar Moderator

    Use "Roles and permission" in dashboard.

    Either by having a member role(lvl1) and then giving some members a support/staff role(lvl2) - that way permissions stack for lvl 2 members.

    (Lvl1 have 1 role, lvl2 have 2 roles, lvl1 and lvl2)


    By having lvl1 have lvl1 role and lvl2 have lvl2 role.

    Adjust permissions accordingly.

    I prefer the first(stack method) as it is easier to kerp an overview - one role for each set(level) of priviliges.

  • Permissions is a great idea but not sure how to do it.

    We want all members to have private access to their own discussions with staff as well as public access to general discussions with other members. One way to do this is to specify which discussions each type of request displays to whom. Grant permissions to the categories so to speak.

  • KasparKaspar Moderator

    Oh, I mistook your comment "from a standing start writing a plugin is not so easy. " as you did not seek a plugin solution anymore, hence I referenced the regular method.

    That would not let you define rights to view individual discussions/comments for some and not for others in the same category.

  • LincLinc Detroit Admin
    edited April 2020

    I will just chime in to say that personally I don't regard this as a minor enhancement. You're trying to add a very big feature to Vanilla, and if you try to approach it as a quick plugin you're gonna write, you will be very disappointed in the outcome (either in how incredibly long it takes, or how incredibly bad it performs in production, or how incredibly frequently it breaks). You should either buckle down for a serious project or hire someone to scope and build it for you.

  • @Linc Thank you for your advice which really is much appreciated. Thanks to Bleistivt who pointed a way forward and to R_J who posted an example to follow I now have the basics in place as an extension to your Resolved plugin. Almost hole in one so little credit to me.

    I am hoping to avoid the ramifications you mention in the short term by restring the scope and by coding category numbers into $wheres selectors. Testing and time will tell.

Sign In or Register to comment.