Registrant Group Addon - Add users to a group if they add a certain code?
Permalink
Hi,
I'm trying to tweak the controller in the Registrant Group addon so it only adds users to a group if they've entered a certain code (12345):
public function on_user_add($userInfo) {
// Get attribute
$ak = CollectionAttributeKey::getByHandle('membership_code');
if ( $ak == "12345") {
$co = new Config();
$gID = $co->get('REGISTRANT_GROUP_ID');
if (!empty($gID)) {
Loader::model('groups');
$group = Group::getByID($gID);
if (!empty($group)) { //check that group wasn't deleted
$userInfo->getUserObject()->enterGroup($group);
}
}
}
This doesn't seem to work, any ideas?
Thanks
Dave
I'm trying to tweak the controller in the Registrant Group addon so it only adds users to a group if they've entered a certain code (12345):
public function on_user_add($userInfo) {
// Get attribute
$ak = CollectionAttributeKey::getByHandle('membership_code');
if ( $ak == "12345") {
$co = new Config();
$gID = $co->get('REGISTRANT_GROUP_ID');
if (!empty($gID)) {
Loader::model('groups');
$group = Group::getByID($gID);
if (!empty($group)) { //check that group wasn't deleted
$userInfo->getUserObject()->enterGroup($group);
}
}
}
This doesn't seem to work, any ideas?
Thanks
Dave
Hello,
There are several problems in your code.
First I am going to assume that you actually did save the code value to an attribute against that user. If you didn't, your code won't do anything.
Second, you are getting the attribute but not it's value for that particular user so it will never be equal to your code
You need to do
There are several problems in your code.
First I am going to assume that you actually did save the code value to an attribute against that user. If you didn't, your code won't do anything.
Second, you are getting the attribute but not it's value for that particular user so it will never be equal to your code
You need to do
$code = $userInfo->getAttribute('membership_code'); if ($code === '12345') {
Thank you both.
I believe I have saved the code correctly because when I view the user in the dashboard, there is the correct value for the attribute.
I've updated the registrant group add-ons controller with your code, but they are still not being added to the group.
What else can I check?
I believe I have saved the code correctly because when I view the user in the dashboard, there is the correct value for the attribute.
I've updated the registrant group add-ons controller with your code, but they are still not being added to the group.
What else can I check?
Start adding echo and/or die statements throughout the code and see what is happening and if it what you expect.
I remember now, I know what the problem is. The on_user_add event is actually fired BEFORE the attributes are saved. There was even an article written about it and I implemented that solution at the time and it worked pretty well.
Basically you need an override to the core to create a new event on_attribute_saved.
The article is here:http://www.werstnet.com/blog/a-more-useful-on-user-add-event-for-co...
If you don't feel like going that way, there is a possible hack. When the user is added, keep the code as it is but put them in a temporary group. Then use the event on_user_enter_group to check the code and put them in the proper group. A 2 step process if you want. I haven't tried it but it should work
Basically you need an override to the core to create a new event on_attribute_saved.
The article is here:http://www.werstnet.com/blog/a-more-useful-on-user-add-event-for-co...
If you don't feel like going that way, there is a possible hack. When the user is added, keep the code as it is but put them in a temporary group. Then use the event on_user_enter_group to check the code and put them in the proper group. A 2 step process if you want. I haven't tried it but it should work
Thanks for the info. I went for the first option you propose.
I've followed the steps and I'm trying to add the user to the group "Franchise" if they add the attribute with the handle "membership_code" or 12345.
I'm not getting an error, but the user isn't being added to the group either. Wish I knew more PHP but it's my weakness for sure.
Here is my user_events.php code:
I've followed the steps and I'm trying to add the user to the group "Franchise" if they add the attribute with the handle "membership_code" or 12345.
I'm not getting an error, but the user isn't being added to the group either. Wish I knew more PHP but it's my weakness for sure.
Here is my user_events.php code:
<?php defined('C5_EXECUTE') or die(_("Access Denied.")); class UserInfoEvents extends Object { public function attributesSaved($ui){ // run your custom code here // the $ui object is the $process variable from the register.php controller // you can do anything here, send a second email to the site admin, // create a custom page for the new user, whatever $u = new User(); //get the current user $ak = $ui->getAttribute('membership_code'); $ak = str_replace(' ', '', $ak); if ( $ak === "12345") { if(!is_object(Group::getByName('Franchise'))) { if(!$u->inGroup(Group::getByName('Franchise'))){ $u->enterGroup('Franchise');
Viewing 15 lines of 21 lines. View entire code block.
You have a problem in your code
This line
Should be
where you delete the exclamation mark
Also I am not 100% sure the new user gets logged in every time. There might be some edge case where he doesn't so you might want to replace
try
This line
if(!is_object(Group::getByName('Franchise'))) {
Should be
if(is_object(Group::getByName('Franchise'))) {
where you delete the exclamation mark
Also I am not 100% sure the new user gets logged in every time. There might be some edge case where he doesn't so you might want to replace
$u = new User();
try
$u = $ui->getUserObject();
Hi,
Thanks for your reply, still struggling to get this working, my user_events code is now:
I tried both with $u = new User(); and with $u = $ui->getUserObject();
Thanks
Thanks for your reply, still struggling to get this working, my user_events code is now:
<?php defined('C5_EXECUTE') or die(_("Access Denied.")); class UserInfoEvents extends Object { public function attributesSaved($ui){ // run your custom code here // the $ui object is the $process variable from the register.php controller // you can do anything here, send a second email to the site admin, // create a custom page for the new user, whatever //$u = new User(); //get the current user $u = $ui->getUserObject(); $ak = $ui->getAttribute('membership_code'); $ak = str_replace(' ', '', $ak); if ( $ak === "123456") { if(is_object(Group::getByName('Franchise'))) { if(!$u->inGroup(Group::getByName('Franchise'))){
Viewing 15 lines of 22 lines. View entire code block.
I tried both with $u = new User(); and with $u = $ui->getUserObject();
Thanks
Could you just post the whole code here, it would be easier
Just thinking, when users register, I've enabled email validation so they need to click the link, then login.
Will this work with this code?
Will this work with this code?
You could use different events then. Try on_user_validate or on_user_activate
I've got it set to on_user_validate in site_events.php file:
However, I'm using the Event Tester addon and it doesn't seem to befiring, there is nothing in the logs when I validate the users email.
My user_events.php is:
I've enabled events in the config too, site.php, although just read this is only needed for older versions of C5 anyway:
And my register.php controller:
When I log in as admin and check the newly registered user, I can see my custom attribute (Franchise) is correct saved under the users' attributes but they aren't being added to the correct group.
Any idea why it doesn't appear to be firing that event?
Thanks
<?php // syntax is like this: // Events::extend($event, $class, $method, $filename, $params = array()); // so we need ours to look like this: Events::extend('on_user_validate', 'UserInfoEvents', 'attributesSaved', 'models/user_events.php'); ?>
However, I'm using the Event Tester addon and it doesn't seem to befiring, there is nothing in the logs when I validate the users email.
My user_events.php is:
<?php defined('C5_EXECUTE') or die(_("Access Denied.")); class UserInfoEvents extends Object { public function attributesSaved($ui){ // run your custom code here // the $ui object is the $process variable from the register.php controller // you can do anything here, send a second email to the site admin, // create a custom page for the new user, whatever //$u = new User(); //get the current user $u = $ui->getUserObject(); $ak = $ui->getAttribute('membership_code'); $ak = str_replace(' ', '', $ak); if ( $ak === "12345") { if(is_object(Group::getByName('Franchise'))) { if(!$u->inGroup(Group::getByName('Franchise'))){
Viewing 15 lines of 22 lines. View entire code block.
I've enabled events in the config too, site.php, although just read this is only needed for older versions of C5 anyway:
... define('ENABLE_APPLICATION_EVENTS', true);
And my register.php controller:
<?php defined('C5_EXECUTE') or die("Access Denied."); class RegisterController extends Concrete5_Controller_Register { public function do_register() { $registerData['success']=0; $userHelper = Loader::helper('concrete/user'); $e = Loader::helper('validation/error'); $ip = Loader::helper('validation/ip'); $txt = Loader::helper('text'); $vals = Loader::helper('validation/strings'); $valc = Loader::helper('concrete/validation'); $username = $_POST['uName']; $password = $_POST['uPassword']; $passwordConfirm = $_POST['uPasswordConfirm']; // clean the username
Viewing 15 lines of 191 lines. View entire code block.
When I log in as admin and check the newly registered user, I can see my custom attribute (Franchise) is correct saved under the users' attributes but they aren't being added to the correct group.
Any idea why it doesn't appear to be firing that event?
Thanks
You have a problem in your join controller code. you are trying to fire that event yourself:
Don't do that.
First, at this point, the user is not validated yet. The user is only validated when he clicks on the link in the email sent to him. If registration doesn't require validation, that event is never fired.
Second, the event is fired by Concrete5 itself so you shouldn't do it in your code.
Here's what happens when you ask for email validation and the user receives an email asking to click a link to validate their email:
The link opens the login page and calls the function v() that you can find in the login single page's controller
That function checks that the link is genuine and then validate the user by calling the function markValidated() which is in concrete\core\models\userinfo.php
And you can see that the proper event is fired in that function.
So my advice is delete that line from your own code and try again.
Events::fire('on_user_validate', $process);
Don't do that.
First, at this point, the user is not validated yet. The user is only validated when he clicks on the link in the email sent to him. If registration doesn't require validation, that event is never fired.
Second, the event is fired by Concrete5 itself so you shouldn't do it in your code.
Here's what happens when you ask for email validation and the user receives an email asking to click a link to validate their email:
The link opens the login page and calls the function v() that you can find in the login single page's controller
// responsible for validating a user's email address public function v($hash = '') { $ui = UserInfo::getByValidationHash($hash); if (is_object($ui)) { $ui->markValidated(); $this->set('uEmail', $ui->getUserEmail()); $this->set('validated', true); } }
That function checks that the link is genuine and then validate the user by calling the function markValidated() which is in concrete\core\models\userinfo.php
function markValidated() { $db = Loader::db(); $v = array($this->uID); $db->query("update Users set uIsValidated = 1, uIsFullRecord = 1 where uID = ?", $v); $db->query("update UserValidationHashes set uDateRedeemed = " . time() . " where uID = ?", $v); Events::fire('on_user_validate', $this); return true; }
And you can see that the proper event is fired in that function.
So my advice is delete that line from your own code and try again.
Thanks, I have removed that line from the controller.
So the site_events.php file I have created is an override for the on_user_validate in concrete\core\models\userinfo.php?
So the site_events.php file I have created is an override for the on_user_validate in concrete\core\models\userinfo.php?
Still isn't working after removing that line from the controller :(
no the site_events is not an override, it listens to and reacts to events.
I just thought of something. Are you actually modifying the original add-on? IF yes, than the event listening is defined in the package's controller in the on_start function.
Check that and if I'm correct, you can get rid of the site_events stuff and make sure you have the proper on_start event listening in place.
If that still doesn't work, I am afraid there isn't much more I can do unless you're willing to send me the code so I can test it myself.
I just thought of something. Are you actually modifying the original add-on? IF yes, than the event listening is defined in the package's controller in the on_start function.
Check that and if I'm correct, you can get rid of the site_events stuff and make sure you have the proper on_start event listening in place.
If that still doesn't work, I am afraid there isn't much more I can do unless you're willing to send me the code so I can test it myself.
Not using the add-on anymore, I'm following the guide you posted on werstnet.
ok but that tutorial was about a very specific case, acting on saved attribute, which is not what you're doing anymore so I'm not sure it's going to be helpful.
Anyway, as I said, I reached the end of what I can do as I said. I have no other idea.
Anyway, as I said, I reached the end of what I can do as I said. I have no other idea.
Finally found the problem. You can't use enterGroup with a group's name, you need a group object so you can rewrite your code like so
And you probably don't really need to check if the user is already in that group but you can also keep it. The code shouldn't throw an error with or without it.
$group = Group::getByName('Franchise'); if(is_object($group)) { if(!$u->inGroup($group)){ $u->enterGroup($group); } }
And you probably don't really need to check if the user is already in that group but you can also keep it. The code shouldn't throw an error with or without it.
to be
This will give you this user's attribute value, then you can compare it to your specific code and move forward with the rest. I haven't used this add-on before, but I believe this should work.