Newbie help: Additional INSERT after user registers or changes pw?


I don't envision a career in xenForo development, but instead, have a specific need for small "hook" to add to the core xenForo. But as the learning curve is quite steep and the project itself is somewhat small, I thought I might ask some help from the Jedi masters here.

So, I basically one exactly one need that I have in mind:

I need to add an additional INSERT to a non-xenForo table, say dummytable whenever a new user registers or an existing user changes his/her password (by actually changing the password, not by reseting the password).

Say, after such event, I want to make a dummified INSERT of this fashion:

INSERT INTO dummytable(xenforo_user_id, plain_password_for_hackers_to_grasp)
VALUES(<id_of_the_newly_created_user_or_the_one_who_changed_his_pw>, <plain_password>)

Sure, the idea laid out here is dumb -- and trust me, that is not what I intend to do exactly (instead, I want to store the xenForo user ID and pair it with a password that is salted in our main site's way -- to use that separate table via SQL triggers to propagate our main database -- and not to fork with xenForo's own tables).

But it should give you the idea of what I want to do and what variables I want to access.

Now, here's what I have grasped so far from the -- apologies for saying it out loud -- rather patchy developer documentation, tutorials and forum posts here:

I apparently need to create an Add-on, named helpTheHackers. This means I need to create a folder under /libraries/ folder called helpTheHackers and create an index.php file there that will read something like:

class helpTheHackers_index
    public static function plainPassword($class, array &$extend)
        if ($class == 'XenForo_DataWriter_User')
            $extend[] = 'helpTheHackers_DataWriter_User';

Now, I need to create a sub-folder under the helpTheHackers called DataWriter and put there a .php file called User.php, thus having the new folder structure:



The User.php should contain.. Dunno, what? Grasped code from another discussion thread and stole this bit there and modified it a bit:

class helpTheHackers_DataWriter_User extends XFCP_helpTheHackers_DataWriter_User
    protected function _postSave()
        $db = $this->_db;
        if ($this->isInsert() && $this->isChanged('user_id'))
          $db->query("dummytable(xenforo_user_id, plain_password_for_hackers_to_grasp)
VALUES({$visitor.user_id}, '$password')");

After that, I need to go to the Admin CP and add a new Code Event Listener to load_class_datawriter:

Execute Callback: helpTheHackers :: plainPassword

and save that.

That flow doesn't seem to work :) Now that you guys have ROTFLOL'd and gotten back to your chairs, I'd really like to get some ideas on all the steps where I have failed and what I should have done instead?-)



Well-known member
I really would recommend that you use XenForo_Authentication instead. You just need to $stuff = new XenForo_Authentication_Core; $stuff->authenticate($userId, $password_hash).

There are several problems:
0. Minor problems: Class names should start with a capital letter, no index.php is needed as .htaccess blocks access (if you're on other web servers, use UNIX permissions)
Directory structure - For clarity, DataWriters go into the DataWriters folder under the addon, Models go into the Models folder, and so on.
1. The dot syntax for accessing array items is for the template system only (and Lua, if you know what I mean :p) - for PHP code you still want $visitor["user_id"].
2. Unlike vBulletin, variables are very largely not pre-defined. To get the visitor instance, you must grab it by calling the static method XenForo_Visitor::getInstance(). There are two ways to achieve that you want to do in your DWUser class: XenForo_Visitor::getInstance()->getUserId() or XenForo_Visitor::getInstance()->toArray()["user_id"].
3. XenForo hashes the password in the User Model before passing it to the DataWriter - you should override the setPassword method in XenForo_Model_User instead. (Note: DataWriter strictly handles data writing - the Model contains (almost) all the logic you want to use)
4. You still need to use a full SQL query if you wish to use $db->query. If you want to use $db->insert or other fancy things like that, take a look at Zend_Db class here.
5. IIRC Password changes uses an UPDATE.