Activation Required and Emails for Accounts Approved via Member Profile

Started by GL700Wing, February 15, 2021, 06:28:36 AM

Previous topic - Next topic

GL700Wing

I recently created a forum for a business where new members are required to provide specific information at the time they register (this was achieved using Custom Profile fields) and the 'Method of registration employed for new members' is set to 'Admin Approval'.

When a new member joins they receive an email message that contains the following information:
QuoteBefore you can login and start using the forum, your request will be reviewed and approved.  When this happens, you will receive another email from this address.

Employees of the business are responsible for reviewing and then either approving or rejecting membership requests and I discovered today that, rather than approving/rejecting membership requests via the Administration Center, they are doing this from within the individual member profiles so that they can review the required information that was supplied when the new member registered.

I was curious as to what action the 'approve' link in the member profile actually performed (ie, 'Approve', 'Approve and send email' or 'Approve and Require Activation') so I tested it only to discover that all it does is 'Approve' the account (ie, the account is activated, the new member does not receive an email message advising that their account has been approved/activated, and the new member is not required to activate their account).

Apparently this is a known non-issue but the challenge for this business is that they had no idea that when they approved an account via the forum profile the new member was not being sent an email notification to let them know.  In addition to wanting members to be notified via email when their account has been approved the business also wants email activation for all new accounts to ensure that the email address provided is valid.

To satisfy these requirements I did the following:
1.  Split the existing 'Activate Account' functionality in 'Profile' management into 'Approve Account' and 'Activate Account';
2.  Added requirement for activation with email notification when accounts awaiting admin approval are approved via a member's profile;
3.  Added email notification for accounts that are manually activated via a member's profile; and
4.  Added the option to approve 'Under Age' accounts via a member's profile.




In ./Sources/Profile.php
Find:
'activateaccount' => array(
Add Before:
'approveaccount' => array(
'file' => 'Profile-Actions.php',
'function' => 'approveAccount',
'sc' => 'get',
'permission' => array(
'own' => array(),
'any' => array('moderate_forum'),
),
),


Find:
// Now call the sub-action function...
if ($current_area == 'activateaccount')

Replace With:
// Now call the sub-action function...
if ($current_area == 'approveaccount')
{
if (empty($post_errors))
approveAccount($memID);
}
elseif ($current_area == 'activateaccount')



In ./Sources/Profile-Actions.php
Find:
// Activate an account.
function activateAccount($memID)
{
global $sourcedir, $context, $user_profile, $modSettings;

isAllowedTo('moderate_forum');

if (isset($_REQUEST['save']) && isset($user_profile[$memID]['is_activated']) && $user_profile[$memID]['is_activated'] != 1)
{
// If we are approving the deletion of an account, we do something special ;)
if ($user_profile[$memID]['is_activated'] == 4)
{
require_once($sourcedir . '/Subs-Members.php');
deleteMembers($context['id_member']);
redirectexit();
}

// Let the integrations know of the activation.
call_integration_hook('integrate_activate', array($user_profile[$memID]['member_name']));

// We need to log that we're doing something.
logAction('approve_member', array('member' => $memID), 'admin');

// Actually update this member now, as it guarantees the unapproved count can't get corrupted.
updateMemberData($context['id_member'], array('is_activated' => $user_profile[$memID]['is_activated'] >= 10 ? 11 : 1, 'validation_code' => ''));

// If we are doing approval, update the stats for the member just in case.
if (in_array($user_profile[$memID]['is_activated'], array(3, 4, 13, 14)))
updateSettings(array('unapprovedMembers' => ($modSettings['unapprovedMembers'] > 1 ? $modSettings['unapprovedMembers'] - 1 : 0)));

// Make sure we update the stats too.
updateStats('member', false);
}

// Leave it be...
redirectexit('action=profile;u=' . $memID . ';area=summary');
}

Replace With:
// Approve an account.
function approveAccount($memID)
{
global $sourcedir, $context, $user_profile, $modSettings, $language, $scripturl;

isAllowedTo('moderate_forum');

if (isset($_REQUEST['save']) && isset($user_profile[$memID]['is_activated']) && in_array($user_profile[$memID]['is_activated'], array(3, 4, 5, 13, 14, 15)))
{
require_once($sourcedir . '/Subs-Members.php');

// If we are approving the deletion of an account, we do something special ;)
if ($user_profile[$memID]['is_activated'] == 4 || $user_profile[$memID]['is_activated'] == 14)
{
deleteMembers($context['id_member']);
redirectexit();
}

// Let the integrations know of the activation.
call_integration_hook('integrate_activate', array($user_profile[$memID]['member_name']));

// We need to log that we're doing something.
logAction('approve_member', array('member' => $memID), 'admin');

// Generate a random activation code.
$validation_code = generateValidationCode();

// Actually update this member now, as it guarantees the unapproved count can't get corrupted.
updateMemberData($context['id_member'], array('is_activated' => $user_profile[$memID]['is_activated'] >= 10 ? 11 : 0, 'validation_code' => $validation_code));

// If we are doing approval, update the stats for the member just in case.
updateSettings(array('unapprovedMembers' => ($modSettings['unapprovedMembers'] > 1 ? $modSettings['unapprovedMembers'] - 1 : 0)));

// Make sure we update the stats too.
updateStats('member', false);

// Send activation email
$replacements = array(
'USERNAME' => $user_profile[$memID]['member_name'],
'ACTIVATIONLINK' => $scripturl . '?action=activate;u=' . $memID . ';code=' . $validation_code,
'ACTIVATIONLINKWITHOUTCODE' => $scripturl . '?action=activate;u=' . $memID,
'ACTIVATIONCODE' => $validation_code,
);

require_once($sourcedir . '/Subs-Post.php');
$language = empty($user_profile[$memID]['lngfile']) || empty($modSettings['userLanguage']) ? $language : $user_profile[$memID]['lngfile'];
$emaildata = loadEmailTemplate('admin_approve_activation', $replacements, $language);
sendmail($user_profile[$memID]['email_address'], $emaildata['subject'], $emaildata['body'], null, null, false, 0);
}

// Leave it be...
redirectexit('action=profile;u=' . $memID . ';area=summary');
}

// Activate an account.
function activateAccount($memID)
{
global $sourcedir, $context, $user_profile, $modSettings, $language, $scripturl;

isAllowedTo('moderate_forum');

if (isset($_REQUEST['save']) && isset($user_profile[$memID]['is_activated']) && !in_array($user_profile[$memID]['is_activated'], array(1, 3, 4, 5, 13, 14, 15)))
{
// Let the integrations know of the activation.
call_integration_hook('integrate_activate', array($user_profile[$memID]['member_name']));

// We need to log that we're doing something.
logAction('approve_member', array('member' => $memID), 'admin');

// Actually update this member now, as it guarantees the unapproved count can't get corrupted.
updateMemberData($context['id_member'], array('is_activated' => $user_profile[$memID]['is_activated'] >= 10 ? 11 : 1, 'validation_code' => ''));

// Make sure we update the stats too.
updateStats('member', false);

// Send approval email
$replacements = array(
'NAME' => $user_profile[$memID]['member_name'],
'USERNAME' => $user_profile[$memID]['real_name'],
'PROFILELINK' => $scripturl . '?action=profile;u=' . $memID,
'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder',
);

require_once($sourcedir . '/Subs-Post.php');
$language = empty($user_profile[$memID]['lngfile']) || empty($modSettings['userLanguage']) ? $language : $user_profile[$memID]['lngfile'];
$emaildata = loadEmailTemplate('admin_approve_accept', $replacements, $language);
sendmail($user_profile[$memID]['email_address'], $emaildata['subject'], $emaildata['body'], null, null, false, 0);
}

// Leave it be...
redirectexit('action=profile;u=' . $memID . ';area=summary');
}



In ./Sources/Profile-View.php
Find:
// Should we show a custom message?
$context['activate_message'] = isset($txt['account_activate_method_' . $context['member']['is_activated'] % 10]) ? $txt['account_activate_method_' . $context['member']['is_activated'] % 10] : $txt['account_not_activated'];

Add After:
if (in_array($context['member']['is_activated'], array(3, 4, 5, 13, 14, 15)))
$context['approve_message'] = $context['activate_message'];



In ./Themes/default/Profile.template.php
Find:
// Is this member requiring activation and/or banned?
if (!empty($context['activate_message']) || !empty($context['member']['bans']))
{

// If the person looking at the summary has permission, and the account isn't activated, give the viewer the ability to do it themselves.
if (!empty($context['activate_message']))

Replace With:
// Is this member requiring approval, activation and/or banned?
if (!empty($context['approve_message']) || !empty($context['activate_message']) || !empty($context['member']['bans']))
{
// If the person looking at the summary has permission, and the account isn't approved, give the viewer the ability to do it themselves.
if (!empty($context['approve_message']))
echo '
<dt class="clear"><span class="alert">', $context['approve_message'], '</span>&nbsp;(<a href="' . $scripturl . '?action=profile;save;area=approveaccount;u=' . $context['id_member'] . ';' . $context['session_var'] . '=' . $context['session_id'] . '">', $context['activate_link_text'], '</a>)</dt>';
// If the person looking at the summary has permission, and the account isn't activated, give the viewer the ability to do it themselves.
elseif (!empty($context['activate_message']))
Life doesn't have to be perfect to be wonderful ...

Slava
Ukraini!
"Before you allow people access to your forum, especially in an administrative position, you must be aware that that person can seriously damage your forum. Therefore, you should only allow people that you trust, implicitly, to have such access." -Douglas

Advertisement: