With the assistance of a very kind and patient individual (from the EE boards), I was able to put together an extension that re-assigns a pending user accounts’ member_group to one selected by the prospective user at account registration. The extension works in conjunction with the addition of a Custom Profile Field (Pulldown) to the EE registration form which contains user-friendly names for each of the member_groups available.
Now for the fun stuff. The catch is this current extension works off the cp_members_validate_members hook which fires when a site admin accesses the CP and approves Pending members: Admin > Members And Groups > Activate Pending Members.
All fine and dandy - here is where my situation begins to unravel. I need to change this process to act on “Self-activated” accounts using the member_register_validate_members hook. I am lost as to how to access the pending account information in order to begin the process of member_groups re-assignment.
One more wrinkle, I also need to perform this process if the user updates their account preferences; changing their member_group, which would fire off the member_update_preferences hook.
Now, I started a thread in the How-to forum but thought that since this forum is dedicated to the Discussion & Questions related to extension development that this would be a more appropriate location for my questions. Please be gentle, my scripting skills are limited at best. If anyone could lend some assistance, it would be greatly appreciated.
Thanks in advance.
[Moderator Edit: Shortened Topic for display purposes]
Hi hothouse,
I’ve recently posted up an FR for the change in position of this hook within the code, or a change to the data sent to this extension call. For not the same reason, but similar. So by all means please add your voice to that :]
What you may have to do to be able to use this hook more effectively in the short term is slightly modify the core file (mod.member_register.php) and move a single line from above the hook to below the hook. Always back up before doing crazy things like this ;]
All I had done, is move this line:
$DB->query("UPDATE exp_members SET authcode = '' WHERE authcode = '$id'");
To below the call to the extension. You can grab the $id variable you see in that query from the $IN class (see below.) and perform whatever you need to do to that member.
global $IN, $DB;
$id = $DB->escape_str($IN->GBL('id'));
Hey, thanks for responding.
So, if I, taking all the necessary precautions, move the indicated DB query to below the current hook position, I could do something like:
function updateUsers_member_group()
{
global $IN, $DB;
$id = $DB->escape_str($IN->GBL('id'));
/* Do I need to perform a query for $group_id ? */
foreach ($id)
{
if($group_id == '5'); //default member group
{
$query = $DB->query("select m_field_id_1 from exp_member_data where member_id='$val'") ; //now grab the value of your custom field
$user_groupChoice = ($query->row['m_field_id_1']); //and load it into your variable
echo $user_groupChoice; // see if we have our value
switch ($user_groupChoice)
{
case "group 1":
$new_group_id = '6';
break;
case "group 2":
$new_group_id = '7';
break;
case "group 3":
$new_group_id = '8';
break;
default: //default is the all others bucket
$new_group_id = '5'; //can't figure out how to assign so leave in 'pending';
break;
}
$DB->query("UPDATE exp_members SET group_id = $new_group_id WHERE member_id = '".$DB->escape_str($val)."'");
}
}
Thank look like it makes sense?
Not quite, but you’re on the right-ish track…
function update_users_member_group()
{
global $IN, $DB;
// Get 'authcode' from request
$id = $DB->escape_str($IN->GBL('id'));
// Check for the existence of their group choice, or default to 5
// Change both field_id_n to relevant field id
$query = $DB->query("SELECT md.field_id_n FROM exp_member_data AS md LEFT JOIN exp_members AS m ON m.member_id = md.member_id LEFT JOIN exp_member_groups AS mg ON mg.group_id = md.field_id_n WHERE m.authcode = '{$id}'");
switch($query->num_rows)
{
case '1':
$group_choice = $DB->escape_str($query->row['field_id_n']);
break;
case '0': default:
$group_choice = '5';
break;
}
// Update member and finished :D
$DB->query("UPDATE exp_members SET group_id = '{$group_choice}' WHERE authcode = '{$id}' LIMIT 1");
}
We only need 1 query to check for the field and the validity of their choice 😊
EDIT: That is, if the value stored in the member data table is just the group id…
Wow…I’m not too sure I would have ended with the query you have on my own.
So…I’ve made the change to mod.member_register.php and I’ve updated the extension to reflect your suggestions (I’ve attached a text file showing the entire ext.).
Not I have an error posting to the users confirmation page: Warning: call_user_func_array() [function.call-user-func-array]: First argumented is expected to be a valid callback, ‘membergroup_update::updateUsers_member_group’ was given in (appendingURL)/core/core.extensions.php on line 255
I’m not too sure what to make of this. The user account did validate but the user group re-assignment which the extension is supposed to perform did not - the users was placed in the default member group though a selection was made during registration.
Any ideas?
I should have been paying closer attention to what I was doing…sorry I missed that.
I have that issue corrected. Now I’m dealing with query errors. I’ve updated the initial field (that is referenced at the beginning and end of the query) name to reflect what is occurring in my DB (from md.field_id_n to m_field_id_1). I also changed the reference to the field name in the case #1.
The extension no longer throws any errors but it also does not reassign the member to their requested member group; in fact, they are not even assigned to the default group. When I checked the DB it shows that the group id is set to “0” - which is not any of the options being offered.
Another point to note, the authcode for each user remains unpopulated in the DB after going thru the self-validation process.
Here is what I currently have:
function updateUsers_member_group()
{
global $IN, $DB;
// Get 'authcode' from request
$id = $DB->escape_str($IN->GBL('id'));
// Check for the existence of their group choice, or default to 5
// Change both field_id_n to relevant field id -
$query = $DB->query("SELECT m_field_id_1 FROM exp_member_data AS md LEFT JOIN exp_members AS m ON m.member_id = md.member_id LEFT JOIN exp_member_groups AS mg ON mg.group_id = m_field_id_1 WHERE m.authcode = '{$id}'");
switch($query->num_rows)
{
case '1':
$group_choice = $DB->escape_str($query->row['m_field_id_1']);
break;
case '0': default:
$group_choice = '5';
break;
}
// Update member and finished :D
$DB->query("UPDATE exp_members SET group_id = '{$group_choice}' WHERE authcode = '{$id}' LIMIT 1");
}
The group choice filed name for each member (SELECT * FROM exp_member_data) is m_field_id_1. Should I be updating any other references in this query?
Sorry if I sound a bit lame…this is not my forte.
I wrote two extensions just two days ago to avoid having to edit the mod.member_register.php file. The procedure I used to change the member group upon self activation is to hook into the member_member_register hook where in the $data you’ll find the member id in the following way:
function my_function ( $data )
{
global $DB, $IN;
// Get unique member id
$unique_member_id = $data['unique_id'];
// Look up member_id in members db
$query = $DB->query("SELECT member_id FROM exp_members WHERE unique_id = '".$DB->escape_str($unique_member_id)."'");
I then do some processing needed for the functionality I am after and insert the member_id and the desired member group id into a custom table. This information will be used by the second extension upon self activation.
The second extension hooks into the member_register_validate_members hook and matches the member id in my custom table and in the members table making sure there is no authorisation code and the member is part of the default member group to avoid changing the wrong members member group.
// Retrieve the matching member ids and get the group_id to use for my functionality
// make sure the member_ids have no authorization code anymore and are
// marked as default member group
$default_group_id = $PREFS->ini('default_member_group');
// Build and perform query
$pending_members = $DB->query("SELECT exp_members.member_id, exp_members.group_id, exp_custom_table.cc_member_id, exp_custom_table.cc_member_group_id
FROM exp_members, exp_custom_table
WHERE exp_members.member_id = exp_custom_table.cc_member_id
AND exp_members.authcode = ''
AND exp_members.group_id = '".$default_group_id."'
");
// Set member and group id
$member_id = $pending_members->row['member_id'];
$group_id = $pending_members->row['cc_member_group_id'];
// Change the member group for this member
$DB->query("UPDATE exp_members SET group_id = '".$DB->escape_str($group_id)."'
WHERE member_id = '".$DB->escape_str($member_id)."'");
// Delete entry from exp_custom_table table
$DB->query("DELETE FROM exp_custom_table WHERE cc_member_id= '".$member_id."'");
So, hope this gives you an insight into an alternative method.
I wrote two extensions just two days ago to avoid having to edit the mod.member_register.php file…
Hello Sintra,
I do like the fact that your example does not rely on altering the mod.member_register.php file. With that said, my experience is limited at best and though I understand conceptually what you are doing, my handle on accessing info from a DB (constructing queries) really prevents me from moving from where I am above to what you’re subscribing to without a tremendous amount of hand holding.
For instance, I have gone down a path that attempts to access the data from a required custom field in my registration form for each prospective member which I then associate with my member-group ID’s. This makes perfect sense to me.
It seems what your doing is allowing mod.member_register.php to do what it is intended to - letting it put pending members who are self-activating into the default member group. Then you are evaluating for the member_ID and to see if that member is in the default member group, if true, you re-assign that member to a new member group.
I guess what I’m missing though is why there is a need for 2 ext. and how you determine what member_group to reassign the pending member to?
I guess what I’m missing though is why there is a need for 2 ext. and how you determine what member_group to reassign the pending member to?
To answer the first question: I use two extension because the member_register_validate_members hook doesn’t allow me to know who just self-activated. There is no member_id and the authorcode has just been removed before the hook. So, I can’t just grab that data and work with it. Therefore I use the first extension as explained above. There I catch the member_id which I can later use when the member self activates and the second extension is called.
Second question: Upon member registration members can enter a code into a custom member field. I match that potential code ( not everyone will have one ) against a database and upon a found match I want that member to be assigned to one specific member group.
So, if I understand correctly what you are trying to achieve it is virtually the same in the sense you are going to match the members prefered member group to a database with those member group ids. Is that correct?
To answer the first question: I use two extension because the member_register_validate_members hook doesn’t allow me to know who just self-activated. There is no member_id and the authorcode has just been removed before the hook.
Explain no more…I understand!
So, if I understand correctly what you are trying to achieve it is virtually the same in the sense you are going to match the members prefered member group to a database with those member group ids. Is that correct?
Exactly.
Each pending member is required to select from a series of options provided in a custom-profile field drop-down during registration. This value is then accessible per user via the SELECT * FROM exp_member_data table, the field named m_field_id_1 contains the users selection.
From there I was thinking that I would simply switch thru each case (option) which would assign that member to the member group they had selected.
Assuming you’ve created a table called ‘exp_custom_table’ the first extension could be something like:
function member_group_pre ( $data )
{
global $DB, $IN;
// Get unique member id
$unique_member_id = $data['unique_id'];
// Look up member_id in members db
$query = $DB->query("SELECT member_id FROM exp_members WHERE unique_id = '".$DB->escape_str($unique_member_id)."'");
// Do we find an id? If so use it, if not return
if ( ! $query->num_rows == 0)
{
// set the member id
$member_id = $query->row['member_id'];
} else
{
return;
}
// get the member's prefered member group
$member_group = $DB->query("SELECT m_field_id_1
FROM exp_member_data
WHERE member_id = '".$DB->escape_str($member_id)."'");
if ($member_group->num_rows == 0)
{
return FALSE; // No member_group entered by user
} else
{
// Enter member and prefered group id into the exp_custom_table to be used by exp_member_group extension to change member group upon self activation
$DB->query("INSERT INTO exp_custom_table (custom_table_id, custom_table_member_id, custom_table_member_group_id) VALUES ('', '".$member_id."', '".$member_group->row['m_field_id_1']."')");
return;
}
}
}
// END
In the second extension the main function could go like:
function company_code_main ( )
{
global $DB, $LOC, $PREFS;
// Retrieve the matching member ids and get the group_id to use for the change
// make sure the member_ids have no authorization code anymore and are
// marked as default member group
$default_group_id = $PREFS->ini('default_member_group');
// Build and perform query
$pending_members = $DB->query("SELECT exp_members.member_id, exp_members.group_id, exp_custom_table.cc_member_id, exp_custom_table.cc_member_group_id
FROM exp_members, exp_custom_table
WHERE exp_members.member_id = exp_custom_table.cc_member_id
AND exp_members.authcode = ''
AND exp_members.group_id = '".$default_group_id."'
");
// Set member and group id
$member_id = $pending_members->row['member_id'];
$group_id = $pending_members->row['cc_member_group_id'];
switch($group_id)
{
case 'group 1':
$member_group_id = '7';
break;
case 'default': default:
$member_group_id = '5';
break;
}
// Change the member group for this member
$DB->query("UPDATE exp_members SET group_id = '".$DB->escape_str($member_group_id)."'
WHERE member_id = '".$DB->escape_str($member_id)."'");
// Delete entry from exp_custom_table table
$DB->query("DELETE FROM exp_custom_table WHERE cc_member_id= '".$member_id."'");
return; // carry on
}
// END
Be aware that I didn’t debug/check the code as I posted it here but guess this will be close to what you need.
I have attached a module that inserts a table called exp_custom_membergroup in the DB. Install the folder into your system/modules/ folder and copy the language file into system/language/en/ folder.
Then install the module through your CP.
You can use the code as I posted before in your extensions and replace ‘exp_custom_table’ with ‘exp_custom_membergroup’ and replace the fieldnames ‘custom_table_id’ with ‘key_id’, ‘cc_member_id’ with ‘custom_member_id’ and ‘custom_table_member_group_id’ with ‘custom_member_group_id’.
Hope this gets you going. 😊 Let me know.
Packet Tide owns and develops ExpressionEngine. © Packet Tide, All Rights Reserved.