Please upgrade here. These earlier versions are no longer being updated and have security issues.
HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.

Can someone help me making a warn addon?

I don't know how to make addon's so I thought you might help me with one. A warning add-on.

Description:

There should be a little button on Every user's profile that should be visible by some roles, not others. A admin should be able to allow witch roles can see it and can't by the role and permission on the settings/dashboard. When you click it it should take to to a page with 3 boxes.

B = A box

User to warn

"B"

Your name

"B"

Description for warning:

"B"

When they click submit It should appear on the top of there discussion's page like where awards appear only It doesn't go on there profile.

Please reply,

Martin

(P.S Please can it be free)

Comments

  • 422422 Developer MVP
    edited January 2012

    There was an error rendering this rich post.

  • 422422 Developer MVP

    Do you pay by the typed letter for internet usage lol

    There was an error rendering this rich post.

  • ToddTodd Chief Product Officer Vanilla Staff

    Okay, I'm going to unwrap this question and tell you how I'd go about implementing it.

    1. Add a Link to the User's Profile

    Usually when I want to add something to a page I enable the eventi plugin. This plugin shows you where all of the events get thrown. Then you can hook into them and echo stuff out on the page.

    However, in this case I wouldn't see an event in the right place so I have to do a bit more searching. Looking at the profile page I see a list of links on the left. This looks like a good place to add the warning link too. So what I do is search through the project for a piece of text in that menu. Searching for "Change Picture" I see that it is in /application/dashboard/controllers/class.profilecontroller.php with a line that looks like this:

    $SideMenu->AddLink('Options', T('Change Picture'), '/profile/picture/'.$this->User->UserID.'/'.Gdn_Format::Url($this->User->Name), 'Garden.Users.Edit', array('class' => 'PictureLink'));
    

    What I want to do is find a call to $this->FireEvent(...) that I can hook into. What I find is this:

    $this->EventArguments['SideMenu'] = &$SideMenu;
    $this->FireEvent('AfterAddSideMenu');
    

    In order to hook into this event I need to make an event handler that looks like this:

    public function ProfileController_AfterAddSideMenu_Handler($Sender, $Args) {
        $SideMenu = $Args['SideMenu'];
    }
    

    Notice that the $SideMenu is assigned to $this->EventArguments['SideMenu'] before the call to $this->FireEvent('AfterAddSideMenu'). That means I can use it in my event handler.

    So now, how do I add another link to the side menu? Simple, I just need to look at the call that added the 'Change Picture' and do something similar. Let's do something like.

    $SideMenu->AddLink('Options', T('Warn'), '/profile/warn/'.$Sender->User->UserID, 'Garden.Moderation.Manage');
    

    A couple of things to notice here.

    1. I changed $this->User->UserID to $Sender->User->UserID. That's usually what you'll do in event handlers.
    2. The AddLink() method has a handy parameter to only add a link if the current user has a given permission. In this case I'm using the Garden.Moderation.Manage permission.

    Alright on to the next step, which I'll post in a few minutes.

  • ToddTodd Chief Product Officer Vanilla Staff
    edited January 2012

    2. Add the Warn UI

    In my last post I explained how to add a link to the warning page, but now you have to do the warning page. The link is currently going to /profile/warn/<UserID>. This means that we are going to call the Warn method of the ProfileController.

    Guess what? There is no ProfileController->Warn(). We have to create that method in our plugin.

    public function ProfileController_Warn_Create($Sender, $Args) {
       $Sender->Permission('Garden.Moderation.Manage');
    
       $UserID = GetValue(0, $Args);
       $User = Gdn::UserModel()->GetID($UserID);
       if (!$User)
            throw NotFoundException('User');
    
       // Okay, we've got permission to be here and we've been passed an existing user.
       ...
       $Sender->Render('Warn', '', 'plugins/Warnings');
    }
    

    A few things to note.

    1. I always want to check that the current user has permission. I do this with the Gdn_Controller->Permission() method or Gdn::Session()->CheckPermission().
    2. I looked up the user and if they aren't found I call throw NotFoundException(). This is an easy way of bailing out. Vanilla will render the not found page or the proper json and set everything up for you.
    3. The call to $Sender->Render will render the warn.php view of the Warnings plugin. More on this later.
  • ToddTodd Chief Product Officer Vanilla Staff
    edited January 2012

    3. Add the Data to the Warn View.

    You want to add the user that is warning and the user being warned. What you need to do is add that data to the controller before rendering the view.

    $Sender->SetData('User', $User);
    $Sender->SetData('WarningUser', Gdn::Session()->User); // signed in user
    $Sender->Render('Warn', '', 'plugins/Warnings');
    
  • ToddTodd Chief Product Officer Vanilla Staff

    4. Make the Warn View

    Okay, now we need to make the UI for warn.php. Here's some simple code to get you started:

    <?php if (!defined('APPLICATION') exit(); // prevent directly viewing script. 
    
    echo $this->Form->Open();
    echo $this->Form->Errors();
    ?>
    
    <div class="P"><?php echo $this->Data('WarningUser.Name') ?> is warning <?php echo $this->Data('User.Name').</div>
    
    <div class="P">
    <?php
    echo $this->Form->Label('Description', 'Description');
    echo $this->Form->TextBox('Description', array('MultiLine' => TRUE));
    ?>
    </div>
    
    <div class="Buttons">
    <?php
    echo $this->Form->Button('Warn');
    ?>
    </div>
    <?php
    echo $this->Form->Close();
    ?>
    
  • ToddTodd Chief Product Officer Vanilla Staff
    edited January 2012

    5. Save the warning data.

    We've got the warn view and it will post back to us some text with a Description. We now need to save it somehow. I'm going to make this as simple as possible by adding a couple of columns to the User table. I do this in the plugin's Structure() method.

    public function Structure() {
       Gdn::Structure()
            ->Table('User')
            ->Column('WarningUserID', 'int', FALSE)
            ->Column('WarningDescription', 'varchar(255)', FALSE)
            ->Set();
    }
    
    public function Setup() {
        $this->Structure();
    }
    

    This will run whenever the plugin is enabled and when you browse to /utility/update on your forum.

    Now I need to save this data in my plugin. I usually do this before the calls to $Sender->SetData().

    if ($Sender->Form->IsPostBack()) {
       Gdn::UserModel()->SetField($UserID, array(
            'WarningUserID' => Gdn::Session()->UserID,
            'WarningDescription' => $Sender->Form->GetFormValue('Description')
            ));
    
        // Possibly redirect here or give a status message.
    }
    
  • 422422 Developer MVP

    Way to go Todd . Smarty pants ^5

    There was an error rendering this rich post.

  • ToddTodd Chief Product Officer Vanilla Staff
    edited January 2012

    6. Displaying the Warning and Other Considerations

    The final thing to do is to display the warning on the user somewhere. Well, I've given you enough information to make that an exercise you can do yourself. Some things you can think of:

    1. Figure out where you want to display the warning and make an event handler.
    2. Look up the user and the warning to display it.
    3. Echo out the waning.

    This should be enough to make a basic warning plugin. However, maybe you might want to add some features:

    1. There needs to be a way of removing the warning.
    2. Maybe warnings can auto-expire.
    3. Maybe there is a count of warnings so you know when someone has been repeatedly warned.
    4. Maybe there should be a way of banning users that have been warned too may times.
    5. Adding a config page so that people can tweak your options.
  • hbfhbf wiki guy? MVP

    @todd - thank you. You just created one of the single most inclusive pieces of plugin writing documentation i've seen around here. this belongs somewhere special... not buried in a thread.

  • ToddTodd Chief Product Officer Vanilla Staff

    Thanks. Yes, I think I'll grab the stuff and put them in a proper post.

  • JongosJongos
    edited January 2012

    All praise to @Todd !

    Hope there's going to be more posts like this.

    I'd make one like this if I (am confident that I really) know how, but I'm still learning.

    Thumbs up!

    ---off_topic---

    Anyway, Todd....

    Have you checked my post here : Suggestion : Embed Discussion to Documentation Page

    It could accelerate learning process if...

    1. newbies if they could ask about coding or explaination that seems ambiguous to them
    2. devs with solid understanding on Vanilla could give additional short example like on php.net
  • Ok, that guide is just far two hard. I can't understand half of it, where is

    /application/dashboard/controllers/class.profilecontroller.php?

    can you please P.M me with more detail, or make the addon.

  • the file is there...

    It's only an example... When he was referring to that file, he was telling how to find an event to hook to, ie. search for the text FireEvent.

    When you create a plugin, you'd want to hook your plugin to a certain event which is suitable for your purpose.

    That way, when Garden process a Controller that contains that event, it will trigger your plugin.

    Spend some time referring to the Documentation. It's actually easy making add-on for Vanilla... (If you know some Php).

  • hbfhbf wiki guy? MVP

    martin122234567890 said:
    Ok, that guide is just far two hard. I can't understand half of it, where is

    /application/dashboard/controllers/class.profilecontroller.php?

    can you please P.M me with more detail, or make the addon.

    @martin122234567890 Todd's description is pretty inclusive. If you are looking for someone to make the plugin for you it's a bit different than asking for free help. But you're in luck I suppose, PM me and I'll send you my paypal address and price and I'll dev the plugin after the payment clears.

  • ToddTodd Chief Product Officer Vanilla Staff

    Okay, I'm going to put a stop to this now. Unfortunately, Martin is just a young kid and isn't old enough to be a part of the community. We require that community members be at least 13 years of age and I think some people here are being led astray by his questions.

This discussion has been closed.