Change User Group Via PHP

I still use the method Chris described, but a bit differently to make sure that there aren't any duplicates.
Don't.

@HWS solution is likley more, erm, robust (excuse the pun). My approach was either dated or potentially just wrong. It likely works, but there are systems in place to handle it better.
 
Don't.

@HWS solution is likley more, erm, robust (excuse the pun). My approach was either dated or potentially just wrong. It likely works, but there are systems in place to handle it better.
LOL.

I'm trying to get my IDE open to show my exact approach...
 
Code:
            /* @var $dw XenForo_DataWriter_User */
            $dw = XenForo_DataWriter::create('XenForo_DataWriter_User');
            $dw->setExistingData($user['user_id']);
            $secondaryGroups = explode(',', $dw->get('secondary_group_ids'));
            $secondaryGroups[] = $group;
            $dw->setSecondaryGroups($secondaryGroups);
            $dw->save();

I do this right now.
 
Should be ok :)

My previous approach probably wasn't wrong, just not very well executed at least.

The benefit of the user group change system is it does allow changes to be reverted easily. Good use case example is when you create a Moderator or Administrator and specify some additional user groups to place those users into. A user group change is logged with a change key of, e.g. 'moderator', so if that moderator is ever demoted, any user group changes you added will automatically be reverted.

If you don't need that, you might not need to worry about that system, and your approach should be ok.
 
Code:
            /* @var $dw XenForo_DataWriter_User */
            $dw = XenForo_DataWriter::create('XenForo_DataWriter_User');
            $dw->setExistingData($user['user_id']);
            $secondaryGroups = explode(',', $dw->get('secondary_group_ids'));
            $secondaryGroups[] = $group;
            $dw->setSecondaryGroups($secondaryGroups);
            $dw->save();

I do this right now.

Will work, cannot be reverted. And is still 4 lines more (equals 3 times as long!) than the solution I posted above which will get you exactly the same result (plus the bonus of being easily reversible). ;)
 
External login and registration is also very easy to implement in an add-on. Thanks to MVC and data writers. you should get comfortable with it.

Basically, what I was calling the weird world of Xenforo programming is not weird, I just am finding my way to civilization.

Not five minutes ago, I was explaining to my significant other that I need to become more comfortable with MVC, if for no other reason, to get onto the same page as a lot of programmers better than me.

External login and registration is also very easy to implement in an add-on. Thanks to MVC and data writers.
My team is on this one. They are looking for steps 1 through 5, but cannot locate the documentation and most (all) of them are idiots regarding MVC and data writers.

Question from one of my supervisors (between my ears):
How is adding onto to XenForo going to register new members? We need to add something it to our other system, unless Xenforo is going to reach inside it?


What I am picturing is an add on XF that provides functions I can use inside the external programs. When the XF addon is done, how will new members who sign up in my external app get registered into XF?

I will get a lot of these answers naturally as part of making an an add-0n. From I am reading, either Xenforo add-ons are in my programming future, or I am going about my integration problem wrong.

QUESTIONS FROM BEWILDERMENT:

Is a data writer an MVC thing or a Xenforo thing? I googled variations of, data writer MVC, and did not get a hit on what we are talking about.

Regarding MVC, the benefit I see is that is a somewhat well-known standard that has enough flexibility and code samples available, it is a great world. I am not yet viewing MVC is a desirable way of assembling an application.

Is a working start kit available for making an addon, apart from Xenforo itself?
 
Would it adviceble to update the cache afterwards? By adding this just before the dw is saved.

PHP:
$dw->rebuildPermissionCombinationId();

Or by running Rebuild User Caches tool?
 
Is a data writer an MVC thing or a Xenforo thing? I googled variations of, data writer MVC, and did not get a hit on what we are talking about.
XenForo. And DataWriters are the best, modern thing in XenForo. I sure as hell hope, if anything, they get carried onto XF 2.0.

Regarding MVC, the benefit I see is that is a somewhat well-known standard that has enough flexibility and code samples available, it is a great world. I am not yet viewing MVC is a desirable way of assembling an application.
MVC is great organisation and a good 'template' for OOP code. Everything does it's job. It's also great for other developers looking at your code.

Is a working start kit available for making an addon, apart from Xenforo itself?
What'd you mean?
 
Would it adviceble to update the cache afterwards? By adding this just before the dw is saved.

PHP:
$dw->rebuildPermissionCombinationId();

Or by running Rebuild User Caches tool?
The DataWriter's (XenForo_DataWriter_User) _postSave function handles that itself. You just need to run the save function.

Code:
        if ($this->isChanged('user_group_id') || $this->isChanged('secondary_group_ids'))
        {
            $this->rebuildPermissionCombinationId();

/* [...] */
        }
 
The DataWriter's (XenForo_DataWriter_User) _postSave function handles that itself. You just need to run the save function.

Code:
        if ($this->isChanged('user_group_id') || $this->isChanged('secondary_group_ids'))
        {
            $this->rebuildPermissionCombinationId();

/* [...] */
        }

Yes, I am aware of that. I was thinking since the change of the group is done in a custom way and through the Admin Panel, then it might have been adviceble to add the rebuild function to the code too, or running it from the Tools. So the change can be more affective. But on a second thought, it might not be needed since the save function you posted above, will take care of it.
 
Yes, I am aware of that. I was thinking since the change of the group is done in a custom way and through the Admin Panel, then it might have been adviceble to add the rebuild function to the code too, or running it from the Tools. So the change can be more affective. But on a second thought, it might not be needed since the save function you posted above, will take care of it.
I'm a bit confused, the DataWriter itself runs that function. If you run it yourself, it's just redundant, as it's already being ran, if that makes sense?
 
I'm a bit confused, the DataWriter itself runs that function. If you run it yourself, it's just redundant, as it's already being ran, if that makes sense?

Yes, that makes perfect sense. I realise it now that running it with the code would be redundant.
 
MVC is great organisation and a good 'template' for OOP code. Everything does it's job. It's also great for other developers looking at your code.
I'll buy that and I thank you for pointing out the OOP used for MVC. It's also crucial to make code usable by the DCAM (developers coming after me).

I formed a negative view toward MVC on the one system I have done a lot on which is built with MVC in CodeIgnitor. It looked to me like the claims of separating the M from the V from the C were BS. To get the data together in the controller to send to the view, I had to work with M, V, and C all at once or nothing would fit together. To me, that defeated the purpose of the separation. In other words, adding a field to a screen usually meant updating M, V, and C, not just one of them. I positively hate the whole M layer the way I saw it done, with Doctrine. The theory is that it makes the data layer easier to work with. To me, it is a new language to replace one that already is perfect, SQL. To me, SQL is to data what Windows XP was to Windows OS - done and complete. Now, it seems, we change things just to change not because there is a need.

I think there better ways to organize the code for a website than MVC, but I guess the most likely case is that I am wrong and just not seeing MVC correctly yet.

All this said, even if there is a better way than MVC, it is not enough better that it is worth making it confusing to other programmers. That is the reason compelling the use of MVC.
 
XenForo. And DataWriters are the best, modern thing in XenForo. I sure as hell hope, if anything, they get carried onto XF 2.0.
I am looking forward to understanding what makes you say this about the data writer.

I am holding onto skepticism, suspecting the Data Writer is needed as a result of unnecessary complexity in the database schema.
 
I am holding onto skepticism, suspecting the Data Writer is needed as a result of unnecessary complexity in the database schema.

There is no need to use it. You can perfectly write into or read from the database with regular SQL queries. You just loose the predefined additional triggered processes, if you do. But sometimes such additional processes are not needed. Depends on what you like to do.

For example: You can perfectly delete a user from the xf_user table manually without any usage of DataWriters. Then the user will be deleted from there and your XenForo installation will likely be broken. Because the user is referenced and has data sets in several other xf_ tables too. The DataWriter takes care about all that automatically. If you delete a user using the DataWriter, the user will be deleted from all tables automatically, all additional processes (like cache updates, etc.) will be triggered automatically and you do not need to think about them. You just need to trigger the DataWriter for deleting a user. 2 lines of code instead of several 100.
 
I don't know how it has to be done back in 2012, when Chris offered the solution above. But in most recent versions of XenForo the programatic addition (or removal) of a user group to a user account is very easy (assuming we are in a controller):

Code:
$userModel = XenForo_Model::create('XenForo_Model_User');
$userModel->addUserGroupChange($userId, 'any_id_you_like', $groupId);
$userModel->removeUserGroupChange($userId, 'any_id_you_like');

Regarding your comments @Dan Allen :
It won't get better. Modern software is object orientated and follows the MVC model and data writers. It makes it in fact easier to expand the code and the create large applications with a very small bug rate (like XenForo).

External login and registration is also very easy to implement in an add-on. Thanks to MVC and data writers. you should get comfortable with it.
Trying this method now, and I'm having a UIX related issue. The secondary group is added, but it breaks:

Fatal error: Call to undefined method XenForo_Model_Node::getUixNodeCache() in /path/to/public/html/library/Audentio/UIX/Listener/CodeEvent.php on line 129

I'm aware this is an issue with UI.X (our theme) but if anybody could help us out then that'd help me a lot.
 
Trying this method now, and I'm having a UIX related issue. The secondary group is added, but it breaks:

Fatal error: Call to undefined method XenForo_Model_Node::getUixNodeCache() in /path/to/public/html/library/Audentio/UIX/Listener/CodeEvent.php on line 129

I'm aware this is an issue with UI.X (our theme) but if anybody could help us out then that'd help me a lot.

How are you calling the XenForo_Model_Node method? It seems to me that it is not called properly. Can you try something along these lines?

PHP:
$nodeModel = XenForo_Model::create('XenForo_Model_Node');
$nodeModel->getUixNodeCache();

But it would help if you posted more details, like what code you are using, and what are you trying to accomplish.
 
How are you calling the XenForo_Model_Node method? It seems to me that it is not called properly. Can you try something along these lines?

PHP:
$nodeModel = XenForo_Model::create('XenForo_Model_Node');
$nodeModel->getUixNodeCache();

But it would help if you posted more details, like what code you are using, and what are you trying to accomplish.
Well, we're using Kotomi as a bridge to wrap custom PHP files inside the XF framework. I've initialised Kotomi with the following code:
PHP:
// START: Initialise XenForo Framework
$startTime = microtime(true);
$kotomi_indexFile = "./";
$kotomi_container = true;
$fileDir = dirname(__FILE__)."/{$kotomi_indexFile}";
require "{$fileDir}/library/Dark/Kotomi/KotomiHeader.php";

XenForo_Session::startPublicSession();
$visitor = XenForo_Visitor::getInstance();
$user_id = $visitor->getUserId();
// END: Initialise XenForo Framework

Then we need to determine what group to put this user in. That's just standard PHP and isn't relevant to the actual process of changing the group. I use the following code to create a new user model and set the group ID:
PHP:
$userModel = XenForo_Model::create('XenForo_Model_User');
$userModel->removeUserGroupChange($user_id, 'RANDOM_STRING');
$userModel->addUserGroupChange($user_id, 'RANDOM_STRING', 10);

The user is then added to group 10 successfully, but they see an error:
Fatal error: Call to undefined method XenForo_Model_Node::getUixNodeCache() in /path/to/public/html/library/Audentio/UIX/Listener/CodeEvent.php on line 129

The operation is successful but the above error message is the only issue now.

Cheers!
 
UPDATE: It works fine if I disable listeners in the config (which results in the UI.X addon being disabled). There's clearly a clash with the listeners but I don't know where. I've also contacted Audentio, but I need a response ASAP so if anybody can help me I'll be grateful!

Cheers.
 
Top Bottom