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

Feature Request: Log Manual User Additions

SicnusSicnus New
edited January 2015 in Feedback

Hey RJ. First of all, we are LOVING the tool! It's awesome. I can't thank you enough for doing this.

Now the question: Can you add it so that if someone MANUALLY adds a user that the "Applicant Accepter" propagates who added the member? This way you would always know who added members to the system either via a user registration and mod approval, or via manual addition by someone with User Add permissions.

Thanks again!


  • Options
    R_JR_J Ex-Fanboy Munich Admin

    Great that it is so useful. I would think that such an extension would be a bigger change - at least in theory, practically it would be no problem. I think the sense of what you want to see has nothing to do with applicants any more.

    But you could use a workaround: simply give a new user the role applicant. Afterwards edit that user and remove that role. It will be shown in the user table as all the other applicants are.

  • Options
    R_JR_J Ex-Fanboy Munich Admin

    But if you have someone willing to write some code in your team:
    you will need to add something to public function userModel_beforeSave_handler ($Sender) where you have to check if the user id is not yet set (i.e. user is new)

  • Options

    Sadly, we don't have any programmers. :(

    I was thinking for completeness' sake you might want to have that in there. Otherwise, if someone manually adds a user, then the field is blank.

    It wouldn't be a problem if I could simply allow folks to VIEW the Users without being able to ADD new users. We need a bit more finer grained permissions IMHO.

    Even if you won't add it, thanks so much for your time just the same RJ. You've already helped us tons.

  • Options
    R_JR_J Ex-Fanboy Munich Admin

    As I've said before: I don't think this functionality belongs to that plugin but it is really easy. Of no one of you is a programmer, I'll show you how easy it is to extend Vanilla. Maybe you become chief coder of your community ;)

    All over Vanilla there are "events" that "fired" (search Vanillas source code for FireEvent) so that you can influence program flow at that point in processing. If you look at the source of the plugin, you'll find these event hooks being functions that are named like "SomeModel/SomeController_EventName_Handler.
    In this plugin there is UserModel_BeforeSave_Handler.
    Models are the objects that interact with the database. So whenever you are looking that is stored in the database and you want to modify the data before it is saved or you want to do additional action before or after data is saved to the db, you will find the event to hook in a file that is called class.somethingmodel.php

    If you try to take influence on program flow, you will most probably end up with an event that is saved in a file called class.somethingcontroller.php

    When looking through code in the plugins, you'll find that all those functions have a parameter called $Sender. That was hard for me to understand. The $Sender is an object of the class that fires the event we are hooking. As an example add the following right below the public function UserModel_BeforeSave_Handler
    "RequireConfirmEmail" is a (boring) function that is defined in class.usermodel.php and we can only access it this way because inside our function "$Sender" is an instance of the class usermodel.
    If you go to yourforum.com/dashboard/user/edit/1 and press save (you don't have to change anything), you'll notice a colored box at the top of the screen. That's the output of "decho()".

    In most cases, you need some additional information in order to change anything. The crucial information is passed as "EventArguments" so that you can work with it. Try adding decho($Sender->EventArguments); to see which information is passed to the event we are dealing with right now.

    Okay, lets get back to our problem:

        // if accepting is done by changing role
        public function userModel_beforeSave_handler ($Sender) {
            $InsertUserID = Gdn::Session()->UserID;
            $User = $Sender->EventArguments['LoadedUser'];
            $UserID = $User->UserID;

    I hope it's now easy to understand what you see here. The function is called from out of the usermodel at the time before user data is saved to database. The we are declaring some variables:
    1. $InsertUserID. Even if you do not know anything about PHP you can understand that we are trying to get the ID of the currently logged in user - the user of this session.
    2. $User is an object that we get from the EventArguments. It is the user that we are currently looking at if you've pressed save on yourforum.com/dashboard/user/edit/1
    3. $UserID is simply the Id of that user

    Now remember that we are looking at a function that is called before anything is written to db. So when we create a new user, it doesn't have an ID because the IDs are created by the database at the time we insert the data. And you wanted to do something only if new users are saved. So that is what we have to check!

            // new user should be also tracked
            if (!$UserID) {
                $this->_InsertUserID = $InsertUserID;

    That can be read as "if there is no UserID, set internal variable InsertUserID to the currently logged in user and continue doing what you have done before"

    "That's all?!" you ask, "That's all!" I say ;)

    But why...?

    Well, you do not really have t know. Simply look at the rest of the function. What I did was this: check if it is inappropriate to save the InsertUserID and leave the function if yes. Only if there is no reason for leaving, you reach the end of the function which reads like that:

            // now that we've excluded everything else we have to keep the inserting user
            $this->_InsertUserID = $InsertUserID;

    So obviously that must be the magic and so simply copy that in your if clause.

    But now if a user registers himself, his user name will be in the column of the ApplicantAccepter. And if you do not want that, put the if (!$UserID) portion below the if ($InsertUserID == $UserID) paragraph. I'll bet you know be able to understand what effect that will have ;)

    Oh, for sure it will be better to test such things not on your live page!

  • Options
    R_JR_J Ex-Fanboy Munich Admin

    Just forget about what I said about the new user appearing in the ApplicantAccepter column in case a user registers normally. That's pure rubbish.

Sign In or Register to comment.