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

Add extra field in comment discussion

Hello

I'd like to add an extra field in the comment discussion, how can I do it ?

Basically the same thing as this plugins : https://open.vanillaforums.com/addon/discussionextender-plugin but for comments and not discussion

Thank you for you help

Comments

  • You basically have to do two things: create that field in the database and extend the view accordingly.

    While I can give you the code for the database, adding a field is more up to you...

    Create a plugin and add this lines to create a new column


    public function setup() {
       $this->structure();
    }
    
    public function structure() {
       Gdn::structure()->table('Comment')
          ->column('Whatever', 'varchar(191)', false)
          ->set();
    }
    


    Then look at /applications/vanilla/views/post/comment.php and you will find several "$this->fireEvent()" calls. You can make use of them by adding something like that to your plugin:


    public function postController_beforeBodyField_handler($sender) {
       echo '<div class="YourPluginName">;
       echo $sender->Form->textBox('Whatever');
       echo '</div>';
    }
    


    Those are only the basics...

  • mathildemathilde New
    edited October 2019

    Thank you, @R_J it's working !

    I know those are the basics, I only start using Vanilla monday...

    But I'm wondering, how do I do now to print the result of my new field inside the comments list ?

    Than you !

  • It helps to get an understanding of the Model, View, Controller concept. Then you will be able to decide where to look at. It also helps to have an understanding of how things are organized in Vanilla.

    Roughly spoken, Vanilla is a forum application that is based on a framework called Garden. There are two other applications which are alltogether what users and admins see as "Vanilla". For you as a developer there will always be the framework, the applications (the dashboard dealing with the backend, users and things like that, the conversation application which handles the private messages and the vanilla application which adds categories, discussions and comments) and the plugins.

    Some of those are deeply intervoven so that it you cannot make this strict separation all the time, but it helps to navigate to the code you are looking for.

    Based on the above, you are looking for a view of the vanilla application. Therefore /applications/vanilla/views is where you have to look at. But there are numerous subfolders there. In order to decide which one will be of importance to you, you need to take a look at the url of the page you are trying to take influence on. Thats "yourforum.com/discussion/123" and therefore you have to look at the files in the subfolder "discussion". There's a view in there called "comment.php" - sounds promising!

    But it only calls a function "writeComment". You can now either do a full text search for "function writeComment" or try looking into the "helper_functions.php" in the current folder. This time, the helper_functions.php is holding that function. Now look through this function for "$sender->fireEvent('..."

    Let's assume you have something that should be added to the comment info section. There is a line $sender->fireEvent('CommentInfo'); in that view and we can use it like that to add some html to all comments:

    public function discussionController_commentInfo_handler($sender, $args) {
        echo '<span class="MItem MyPluginExtraFieldClassName">';
        echo 'Hello World!';
        echo '</span>';
    }
    

    Great, but "Hello World" is not what you wanted to add. You wanted to show the value of a database column for that comment. Look again at the function writeComment, but this time watch out for "$sender->EventArguments['...". Every variable of writeComments that is added to this array is accessible in the method I've shown above. You can either reference them as (surprise!) $sender->EventArguments or as the $args that is the second parameter of our method.

    Vanilla fetches all columns from the database and therefore your custom field should be available in the variable $args['Comment']. Try it by replacing the echo-Hello-World-rubbish by echo $args['Comment']->Whatever;

    Hooray!

    But be warned! The code above is a security nightmare! Users can enter any text they like, that will be saved to the database and in the end it is printed unfiltered to all other users - that's how xss vulnerabilities are made. Never echo any user input unfiltered. So your method should look like that in the end

    public function discussionController_commentInfo_handler($sender, $args) {
        echo '<span class="MItem MyPluginExtraFieldClassName">';
        echo Gdn_Format::text($args['Comment']->Whatever);
        echo '</span>';
    }
    
  • Thank you for all your explanations ! @R_J I appreciate you take your time to answer me, It helps me a lot to understand

    Just a little detail, I'm wondering. I use a checkbox field like that :

    $Form->CheckBox($Name, 'label', ['value' => '1']);

    But my field is always "required", how can I do to set it as "unrequired" ? Or tell the Form what field is required and what's not ?

    Thank you

  • Believe or not: it's my fault! 😀

    I told you how to create a new column in the database, but not what you are doing there. If you look at library/database/class.databasestructure.php you will see the method column(). You have used it in your plugins structure() method to create the new column. It is defined like that:


       /**
        * Defines a column to be added to $this->table().
        *
        * @param string $name The name of the column to create.
        * @param mixed $type The data type of the column to be created. Types with a length specify the length in brackets.
        * * If an array of values is provided, the type will be set as "enum" and the array will be assigned as the column's Enum property.
        * * If an array of two values is specified then a "set" or "enum" can be specified (ex. array('set', array('Short', 'Tall', 'Fat', 'Skinny')))
        * @param boolean $nullDefault Whether or not nulls are allowed, if not a default can be specified.
        * * TRUE: Nulls are allowed.
        * * FALSE: Nulls are not allowed.
        * * Any other value: Nulls are not allowed, and the specified value will be used as the default.
        * @param string $keyType What type of key is this column on the table? Options
        * are primary, key, and FALSE (not a key).
        * @return $this
        */
       public function column($name, $type, $nullDefault = false, $keyType = false) {
    


    I have adviced to create it with false for the $nullDefault parameter. The result is that NULLs aren't allowed which means that the field is required. If you do not want it to be required use 1 or 0 as the third parameter in the structure.

    After you have changed that, disable and re-enable the plugin or run /utility/structure

  • Thank you ! Everything works now

Sign In or Register to comment.