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

Anyone know of an addon to ban users from a discussion?

On a different forum software there was an addon that allowed moderators to ban people from a thread (discussion)...

Anyone know of such an addon?

«134567

Comments

  • R_JR_J Ex-Fanboy Munich Admin

    No, but it would be realtively easy, I guess. Are you ready to write your first plugin? I would guide you!

  • R_JR_J Ex-Fanboy Munich Admin

    Copy the example plugin folder to a new folder and call it "discussionBan"

    Rename the new plugin file to class.discussionban.plugin.php (lower case)

    Look inside that plugin file for the beginning PluginInfo array. The array key must match the folder "discussionBan"

    The class name must be DiscussionBanPlugin.

    Start by changing the PluginInfo array how you need it and wiping everything inside the plugin class. We will start at zero.

    In the following steps you would have to
    1. add an entry to the discussion option menu (plugin Q&A has code which we could look up)
    2. provide a user search field - we can look that up in the conversations application
    3. I would assume that feature would be used sparsely so the information could be directly saved to the Discussion tables Attributes column, no need for database structure changes
    4. there must be a hook on the BeforeSaveDiscussion event: check if session user is banned, if yes add validation result - simple!

    Basically, that's it!

  • R_JR_J Ex-Fanboy Munich Admin

    There should be a module (that's how "widgets" are called in Vanilla) which shows all banned users in a discussion so that mods can unban users. That would be one additional step, but nothing too complex, either.

  • oh I am definitely going to get to work on this.

  • MikeOlsonMikeOlson
    edited July 2017

    Ok R_J here is what I have so far in my class.dicsussionban.plugin.php file:

    <?php
    /**
     * An example plugin.
     *
     * @copyright 2008-2014 Vanilla Forums, Inc.
     * @license GNU GPLv2
     */
    
    // Define the plugin:
    $PluginInfo['discussionBan'] = array(
        'Description' => 'Grants moderators or permissioned users ability to ban users from specific discussions',
        'Version' => '1.1',
        'RequiredApplications' => array('Vanilla' => '2.1'),
        'RequiredTheme' => false,
        'RequiredPlugins' => false,
        'HasLocale' => false,
        'License' => 'GNU GPL2',
        'SettingsUrl' => '/plugin/example',
        'SettingsPermission' => 'Garden.Settings.Manage',
        'Author' => "Mike Olson",
        'AuthorUrl' => 'http://www.vanillaforums.com'
    );
    
    /**
     * Class DiscussionBanPlugin
     *
     * @see http://docs.vanillaforums.com/developers/plugins
     * @see http://docs.vanillaforums.com/developers/plugins/quickstart
     */
    class DiscussionBanPlugin extends Gdn_Plugin {
    
    
    }
    
    
    ?>
    
  • MikeOlsonMikeOlson
    edited July 2017

    @R_J I also think I have the discussionoptions.php figured out somewhat.

    <?php if (!defined('APPLICATION')) exit(); ?>
    <h1><?php echo $this->Data('Title') ?></h1>
    <div class="">
    <?php
    echo $this->Form->Open();
    echo $this->Form->Errors();
    ?>
    
    <div class="P">
       <?php
    
        echo '<div class="P">';
        echo $this->Form->label('BanUser', 'Ban Users');
        echo wrap($this->Form->textBox('To', array('MultiLine' => true, 'class' => 'MultiComplete')), 'div', array('class' => 'TextBoxWrapper'));
        echo '</div>';
    
       ?>
    </div>
    
    <?php
    echo '<div class="Buttons Buttons-Confirm">', 
       $this->Form->Button(T('OK')), ' ',
       $this->Form->Button(T('Cancel'), array('type' => 'button', 'class' => 'Button Close')),
       '</div>';
    echo $this->Form->Close();
    ?>
    </div>
    
  • ummm I did the code format but it didn't.

  • R_JR_J Ex-Fanboy Munich Admin

    Enclose your code in three ~ signs. I've changed your comments that way.

    First learn something general about plugins: http://docs.vanillaforums.com/developer/plugins/

    If you want to add your own option to discussions, you would have to find out how other plugins do so. The Q&A plugin has the following method:

       public function Base_DiscussionOptions_Handler($Sender, $Args) {
          $Discussion = $Args['Discussion'];
          if (!Gdn::Session()->CheckPermission('Vanilla.Discussions.Edit', TRUE, 'Category', $Discussion->PermissionCategoryID))
             return;
    
          if (isset($Args['DiscussionOptions'])) {
             $Args['DiscussionOptions']['QnA'] = array('Label' => T('Q&A').'...', 'Url' => '/discussion/qnaoptions?discussionid='.$Discussion->DiscussionID, 'Class' => 'Popup');
          } elseif (isset($Sender->Options)) {
             $Sender->Options .= '<li>'.Anchor(T('Q&A').'...', '/discussion/qnaoptions?discussionid='.$Discussion->DiscussionID, 'Popup QnAOptions') . '</li>';
          }
       }
    

    Changed to what should be done in your case it should be similar to this:

    public function base_discussionOptions_handler($sender, $args) {
        // If user hasn't moderator permissions, we do not want to edit anything.
        if (!Gdn::session()->checkPermission('Garden.Moderation.Manage')) {
            return;
        }
    
        if (isset($args['DiscussionOptions'])) {
            $args['DiscussionOptions']['BanDiscussion'] = [
                'Label' => t('Ban User from Discussion'),
                'Url' => '/plugin/bandiscussion/'.$args['Discussion']->DiscussionID,
                'Class' => 'Popup'
            ];
        }
    }
    

    If you want to understaand why that has any effect, you need to look at the following:
    First, this function decides which options to show. At the end of the function, there is a possibility for you to add elemenets
    https://github.com/vanilla/vanilla/blob/release/2.3/applications/vanilla/views/discussion/helper_functions.php#L211

    When the page is rendered, the writeDiscussionOptions is called, which fetches the options with the function above.
    https://github.com/vanilla/vanilla/blob/release/2.3/applications/vanilla/views/discussion/helper_functions.php#L394

    By adding the above given method to your class, you tell Vanilla that there is one additional option to show in a discussion.

    That option would try to open yourforum.com/plugin/bandiscussion/somediscussionid Before that doesn't exist, there will not much happen. Creating that is simple, though. Add

    public function pluginConttroller_banDiscussion_create($sender) {
        decho($sender->RequestArgs, 'Debug', true);
    }
    

    to your plugin and you would see some sample output

  • R_JR_J Ex-Fanboy Munich Admin

    The view that you have given above is a very good start! Save it to /plugins/banDiscussion/views/bandiscussion.php

    Instead of giving that debug output, we now want to render your view.

    Change the lines above to

    public function pluginConttroller_banDiscussion_create($sender) {
        $sender->render('bandiscussion', '', 'plugins/banDiscussion');
    }
    

    Check if using the discussion option now shows your view!

  • @R_J said:

    Changed to what should be done in your case it should be similar to this:

    public function base_discussionOptions_handler($sender, $args) {
        // If user hasn't moderator permissions, we do not want to edit anything.
        if (!Gdn::session()->checkPermission('Garden.Moderation.Manage')) {
            return;
        }
    
        if (isset($args['DiscussionOptions'])) {
            $args['DiscussionOptions']['BanDiscussion'] = [
                'Label' => t('Ban User from Discussion'),
                'Url' => '/plugin/bandiscussion/'.$args['Discussion']->DiscussionID,
                'Class' => 'Popup'
            ];
        }
    }
    

    I get syntax error with the above when I add this into my class.

    <?php
    /**
     * An example plugin.
     *
     * @copyright 2008-2014 Vanilla Forums, Inc.
     * @license GNU GPLv2
     */
    
    // Define the plugin:
    $PluginInfo['discussionBan'] = array(
        'Description' => 'Grants moderators or permissioned users ability to ban users from specific discussions',
        'Version' => '1.1',
        'RequiredApplications' => array('Vanilla' => '2.1'),
        'RequiredTheme' => false,
        'RequiredPlugins' => false,
        'HasLocale' => false,
        'License' => 'GNU GPL2',
        'SettingsUrl' => '/plugin/example',
        'SettingsPermission' => 'Garden.Settings.Manage',
        'Author' => "Mike Olson",
        'AuthorUrl' => 'http://www.vanillaforums.com'
    );
    
    /**
     * Class DiscussionBanPlugin
     *
     * @see http://docs.vanillaforums.com/developers/plugins
     * @see http://docs.vanillaforums.com/developers/plugins/quickstart
     */
    class DiscussionBanPlugin extends Gdn_Plugin {
    
    
    public function base_discussionOptions_handler($sender, $args) {
        // If user hasn't moderator permissions, we do not want to edit anything.
        if (!Gdn::session()->checkPermission('Garden.Moderation.Manage')) {
            return;
        }
        if (isset($args['DiscussionOptions'])) {
            $args['DiscussionOptions']['BanDiscussion'] = [
                'Label' => t('Ban User from Discussion'),
                'Url' => '/plugin/bandiscussion/'.$args['Discussion']->DiscussionID,
                'Class' => 'Popup'
            ];
        }
    }
    
    
    }
    
    
    
    ?>
    
  • Should

            $args['DiscussionOptions']['BanDiscussion'] = [
                'Label' => t('Ban User from Discussion'),
                'Url' => '/plugin/bandiscussion/'.$args['Discussion']->DiscussionID,
                'Class' => 'Popup'
            ];
    

    Instead be

            $args['DiscussionOptions']['BanDiscussion'] = array(
                'Label' => t('Ban User from Discussion'),
                'Url' => '/plugin/bandiscussion/'.$args['Discussion']->DiscussionID,
                'Class' => 'Popup'
            );
    
  • Ok so I think I was right. The option no shows:

    Of course when I click on it a pop up comes up and then I get thrown to a blank screen. This shows and then after a second I get a black screen of nothing. Probably because we still need to tell it what it is supposed to do.

  • Here is what I have so far.

  • Scratch that there was some errors in the paths. This is what I have now.

  • Somewhere along the line we switched from it being discussionBan to banDiscussion os I switched things around.

  • vrijvlindervrijvlinder Papillon-Sauvage MVP

    Just a tip here, a class Popup will only popup content from a pre-existing page or module. I suggest you first create a page where the settings appear, before you pop anything up. The reason why it does not show, is because the js to pop up requires the content to exist somewhere, either as a file or a page rendered. it will create the popup box but will eternally try to load the content.

    You should be trying this out in the stand alone forum and not the embedded forum.

  • I don't have a standalone forum to work with it on. I only have an embedded forum. Ok so with the popup I thought it looked to the view file no?

  • R_JR_J Ex-Fanboy Munich Admin

    If a link has the class "Popup", Vanilla uses Javascript to open the link as a popup. In the text you post was a typo. Most of the code I write down here is completely untested and it might be full of typos and do not even work at all. But most of the time you should be able to make it work with just a few adjustments.

    If your PHP doesn't support the brackets as array definitions, you should update your PHP version.

    By the way: we inserted a link into the menu and links can be opened in their own window. If you want to debug your popup, most of the time you get more information if you open the link in a separate tab.

    And after I did this, I thought it might be better to extend the VanillaController.

    In order to be able to show you in more detail what is needed and what I've done, I've created a github repo. You don't need to understand git itself to look at it. It should simply enable you to track the steps I've made: https://github.com/R-J/discussionBan/commits/master

    I fixed some formattings and a little bit of the view. Here are some of the changes I made explained in more detail:

    The PluginInfo array holds meta information of your plugin, but it also contains magic: if you give a link to a settings page here, there will be an option to open that settings in the plugins overview in the dashboard.
    I cannot think of any permission needed and so I have removed it.
    You can use an array key "Name" which you can fill with any value you like. I have chosen "Discussion Ban"

    There have been a typo in the second method and that's why the link you have created in the menu hasn't found the target. In order to show the view, that view has to be found... $sender->render('viewnamewithoutextension', '', 'plugins/subfolder')
    You have used "discussionBan" in there, but your view was named discussionoptions.php.

    The view uses a form, but that form doesn't exist, so we have to attach it to the class.

    This might be a good point to talk about that $sender that you see everywhere... Vanilla gets extended by hooking into events which are fired throughout Vanillas program flow. If we end our plugins method with ..._create, we create something new. If we use pluginController_discussionBan_create, we create something that is reachable on your domain under plugin/discussionban - quite simple, isn't it?
    And this $sender is an instance of the PluginController that you can find in class.plugincontroller.php. This extends the DashboardController which extends - like any controller in Vanilla - the Gdn_Controller. You can do with $sender whatever you can do with PluginController, DashboardController and Gdn_Controller.
    And what we need to do if we want to use a form, is to create an instance of the form class and attach it to our class $sender = new Gdn_Form();

    In order to have a usable user selector, you need some JavaScript. Since I find that a very tedious work, I simply copied what it needs to the code so that you can dive right now into what is left.

    You have to work with the result of what is entered. Look at the UserModel: it provides a method to get a User object by the name. You would have to loop through all names that have been entered and get the user ids. Use that decho function to see the results. Its ugly, but a quick way to "debug". Look at class.model.php "saveToSerializedColumn" method in order to find out how to save that userIDs to the discussion table.

    I've provided an if/else construct where you can add code for the time when the form has been submitted and when it has been read first. In the else clause, you might want to find out how to get a list of all already saved usernames and display them there.

  • @R_J thanks for this! I am looking at it now, at first look when I enable what you've given me to start with the first post in the discussion disappears for me. I will try and figure out what's going on with that but wondering if anything jumps out at you as to why this may be.

  • disregard the above about the starting topic not displaying.

Sign In or Register to comment.