Seditio Source
Root |
./othercms/b2evolution_7.2.3/inc/users/users.ctrl.php
<?php
/**
 * This file implements the UI controller for settings management.
 *
 * This file is part of the evoCore framework - {@link http://evocore.net/}
 * See also {@link https://github.com/b2evolution/b2evolution}.
 *
 * @license GNU GPL v2 - {@link http://b2evolution.net/about/gnu-gpl-license}
 *
 * @copyright (c)2003-2020 by Francois Planque - {@link http://fplanque.com/}
 * Parts of this file are copyright (c)2004-2006 by Daniel HAHLER - {@link http://thequod.de/contact}.
 *
 * @package admin
 *
 * @todo separate object inits and permission checks
 */
if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );

/**
 * @var AdminUI_general
 */
global $AdminUI;

param( 'user_ID', 'integer', NULL );    // Note: should NOT be memorized (would kill navigation/sorting) use memorize_param() if needed

param_action( 'list' );

param( 'display_mode', 'string', 'normal' );

$tab = param( 'tab', 'string', '' );
$tab3 = param( 'tab3', 'string', '', true );

$AdminUI->set_path( 'users', $tab == 'stats' ? 'stats' : 'users', $tab3 == 'duplicates' ? 'duplicates' : 'list' );

if( !
check_user_perm( 'users', 'view' ) )
{
// User has no permissions to view: he can only edit his profile

   
if( isset($user_ID) && $user_ID != $current_User->ID )
    {
// User is trying to edit something he should not: add error message (Should be prevented by UI)
       
$Messages->add( TB_('You have no permission to view other users!'), 'error' );
    }

   
// Make sure the user only edits himself:
   
$user_ID = $current_User->ID;
    if( !
in_array( $action, array( 'update', 'edit', 'default_settings', 'change_admin_skin' ) ) )
    {
       
header_redirect( regenerate_url( 'ctrl,action', 'ctrl=user&action=edit&user_ID='.$user_ID, '', '&' ) );
    }
}

/*
 * Load editable objects and set $action (while checking permissions)
 */

$UserCache = & get_UserCache();

if( !
is_null($user_ID) )
{  
// User selected
   
if( ($edited_User = & $UserCache->get_by_ID( $user_ID, false )) === false )
    {    
// We could not find the User to edit:
       
unset( $edited_User );
       
forget_param( 'user_ID' );
       
$Messages->add( sprintf( TB_('Requested &laquo;%s&raquo; object does not exist any longer.'), TB_('User') ), 'error' );
       
$action = 'list';
    }
    elseif(
$action == 'list' )
    {
// 'list' is default, $user_ID given
       
if( $user_ID == $current_User->ID || check_user_perm( 'users', 'edit' ) )
        {
           
$action = 'edit';
        }
        else
        {
           
$action = 'view';
        }
       
header_redirect( regenerate_url( 'ctrl,action', 'ctrl=user&action='.$action.'&user_ID='.$user_ID, '', '&' ) );
    }

    if(
$action != 'list' )
    {
// check edit permissions
       
if( ! check_user_perm( 'users', 'edit' )
            &&
$edited_User->ID != $current_User->ID )
        {
// user is only allowed to _view_ other user's profiles
           
$Messages->add( TB_('You have no permission to edit other users!'), 'error' );
           
header_redirect( regenerate_url( 'ctrl,action', 'ctrl=user&action=view&user_ID='.$user_ID, '', '&' ) );
        }
        elseif(
$demo_mode && ( $edited_User->ID <= 7 ) )
        {
// Demo mode restrictions: users created by install process cannot be edited
           
$Messages->add( TB_('You cannot edit the admin and demo users profile in demo mode!'), 'error' );

            if(
strpos( $action, 'delete_' ) === 0 || $action == 'promote' )
            {
// Fallback to list/view action
               
$action = 'list';
            }
            else
            {
               
header_redirect( regenerate_url( 'ctrl,action', 'ctrl=user&action=view&user_ID='.$user_ID, '', '&' ) );
            }
        }
    }
}

/*
 * Perform actions, if there were no errors:
 */
if( !$Messages->has_errors() )
{
// no errors
   
switch( $action )
    {

       
/*
         * We currently support only one backoffice skin, so we don't need a system for selecting the backoffice skin.
        case 'change_admin_skin':
            // Skin switch from menu
            param( 'new_admin_skin', 'string', true );
            param( 'redirect_to', 'url', '' );

            $UserSettings->set( 'admin_skin', $new_admin_skin );
            $UserSettings->dbupdate();
            $Messages->add( sprintf( TB_('Admin skin changed to &laquo;%s&raquo;'), $new_admin_skin ), 'success' );

            header_redirect();
            // EXITED
            break;
        */

       
case 'promote':
           
param( 'prom', 'string', true );

            if( !isset(
$edited_User)
                || !
in_array( $prom, array('up', 'down') )
                || (
$prom == 'up' && $edited_User->get('level') > 9 )
                || (
$prom == 'down' && $edited_User->get('level') < 1 )
              )
            {
               
$Messages->add( TB_('Invalid promotion.'), 'error' );
            }
            else
            {
               
$sql = '
                    UPDATE T_users
                       SET user_level = user_level '
.( $prom == 'up' ? '+' : '-' ).' 1
                     WHERE user_ID = '
.$edited_User->ID;

                if(
$DB->query( $sql ) )
                {
                   
$Messages->add( TB_('User level changed.'), 'success' );
                }
                else
                {
                   
$Messages->add( sprintf( 'Couldn\'t change %s\'s level.', $edited_User->login ), 'error' );
                }
            }
            break;


        case
'delete':
           
/*
             * Delete user
             */

           
if( !isset($edited_User) )
               
debug_die( 'no User set' );

            if(
$edited_User->ID == $current_User->ID )
            {
               
$Messages->add( TB_('You can\'t delete yourself!'), 'error' );
               
$action = 'view';
                break;
            }
            if(
$edited_User->ID == 1 )
            {
               
$Messages->add( TB_('You can\'t delete User #1!'), 'error' );
               
$action = 'view';
                break;
            }

           
// Check if the user is deleted as spammer:
           
$is_spammer = ( param( 'deltype', 'string', '', true ) == 'spammer' );

           
$fullname = $edited_User->dget( 'fullname' );
            if(
param( 'confirm', 'integer', 0 ) )
            {
// confirmed, Delete from DB:

                // Check that this action request is not a CSRF hacked request:
               
$Session->assert_received_crumb( 'user' );

                if ( ! empty(
$fullname ) )
                {
                   
$msg_format = $is_spammer ? TB_('Spammer &laquo;%s&raquo; [%s] deleted.') : TB_('User &laquo;%s&raquo; [%s] deleted.');
                   
$msg = sprintf( $msg_format, $fullname, $edited_User->dget( 'login' ) );
                }
                else
                {
                   
$msg_format = $is_spammer ? TB_('Spammer &laquo;%s&raquo; deleted.') : TB_('User &laquo;%s&raquo; deleted.');
                   
$msg = sprintf( $msg_format, $edited_User->dget( 'login' ) );
                }

               
$send_reportpm = param( 'send_reportpm', 'integer', 0 );
               
$increase_spam_score = param( 'increase_spam_score', 'integer', 0 );
                if(
$send_reportpm || $increase_spam_score )
                {
// Get all user IDs who reported for the deleted user:
                   
$report_user_IDs = get_user_reported_user_IDs( $edited_User->ID );
                }

               
$deleted_user_ID = $edited_User->ID;
               
$deleted_user_email = $edited_User->get( 'email' );
               
$deleted_user_login = $edited_User->get( 'login' );
                if(
$edited_User->dbdelete( $Messages ) !== false )
                {
// User has been deleted successfully
                   
unset( $edited_User );
                   
forget_param( 'user_ID' );
                   
$Messages->add( $msg, 'success' );
                   
syslog_insert( sprintf( 'User %s was deleted.', '[['.$deleted_user_login.']]' ), 'info', 'user', $deleted_user_ID );

                   
// Find other users with the same email address:
                   
$message_same_email_users = find_users_with_same_email( $deleted_user_ID, $deleted_user_email, TB_('Note: the same email address (%s) is still in use by: %s') );
                    if(
$message_same_email_users !== false )
                    {
                       
$Messages->add( $message_same_email_users, 'note' );
                    }

                    if(
$send_reportpm )
                    {
// Send an info message to users who reported this deleted user:
                       
user_send_report_message( $report_user_IDs, $deleted_user_login );
                    }

                    if(
$increase_spam_score )
                    {
// Increase spam fighter score for the users who reported the deleted account:
                       
user_increase_spam_score( $report_user_IDs );
                    }
                }

               
$action = 'list';
               
// Redirect so that a reload doesn't write to the DB twice:
               
header_redirect( '?ctrl=users', 303 ); // Will EXIT
                // We have EXITed already at this point!!
           
}
            else
            {    
// not confirmed, Check for restrictions:
               
memorize_param( 'user_ID', 'integer', true );
                if ( ! empty(
$fullname ) )
                {
                   
$msg = sprintf( TB_('Cannot delete User &laquo;%s&raquo; [%s]'), $fullname, $edited_User->dget( 'login' ) );
                }
                else
                {
                   
$msg = sprintf( TB_('Cannot delete User &laquo;%s&raquo;'), $edited_User->dget( 'login' ) );
                }

               
// Init cascade relations: If we delete user as spammer we also should remove the comments, messages and files:
               
$edited_User->init_relations( array(
                   
'delete_messages' => $is_spammer,
                   
'delete_comments' => $is_spammer,
                   
'delete_files'    => $is_spammer,
                ) );

                if( !
$edited_User->check_delete( $msg, array(), true ) )
                {
// There are restrictions:
                   
$action = 'view';
                }
            }
            break;


        case
'del_settings_set':
           
// Delete a set of an array type setting:
           
param( 'plugin_ID', 'integer', true );
           
param( 'set_path', 'string' );

           
$admin_Plugins = & get_Plugins_admin();
           
$admin_Plugins->restart();
           
$edit_Plugin = & $admin_Plugins->get_by_ID($plugin_ID);

           
load_funcs('plugins/_plugin.funcs.php');
           
_set_setting_by_path( $edit_Plugin, 'UserSettings', $set_path, NULL );

           
$edit_Plugin->Settings->dbupdate();

           
$action = 'edit';

            break;


        case
'add_settings_set': // delegates to edit_settings
            // Add a new set to an array type setting:
           
param( 'plugin_ID', 'integer', true );
           
param( 'set_path', 'string', '' );

           
$admin_Plugins = & get_Plugins_admin();
           
$admin_Plugins->restart();
           
$edit_Plugin = & $admin_Plugins->get_by_ID($plugin_ID);

           
load_funcs('plugins/_plugin.funcs.php');
           
_set_setting_by_path( $edit_Plugin, 'UserSettings', $set_path, array() );

           
$edit_Plugin->Settings->dbupdate();

           
$action = 'edit';

            break;

        case
'search':
           
// Quick search

            // Check that this action request is not a CSRF hacked request:
           
$Session->assert_received_crumb( 'user' );

           
param( 'user_search', 'string', '' );
           
set_param( 'keywords', $user_search );
           
set_param( 'filter', 'new' );

           
load_class( 'users/model/_userlist.class.php', 'UserList' );
           
$UserList = new UserList( 'admin', $UserSettings->get('results_per_page'), 'users_', array( 'join_city' => false ) );
           
$UserList->load_from_Request();
           
// Make query to get a count of users
           
$UserList->query();

            if(
$UserList->get_total_rows() == 1 )
            {    
// If we find only one user by quick search we do a redirect to user's edit page
               
$User = $UserList->rows[0];
                if( !empty(
$User ) )
                {
                   
header_redirect( '?ctrl=user&user_tab=profile&user_ID='.$User->user_ID );
                }
            }

           
// Unset the filter to avoid the step 1 in the function $UserList->query() on the users list
           
set_param( 'filter', '' );

            break;

        case
'remove_sender_customization':
           
// Check that this action request is not a CSRF hacked request:
           
$Session->assert_received_crumb( 'users' );

           
// Check required permission
           
check_user_perm( 'users', 'edit', true );

           
// get the type of the removable sender customization
           
$type = param( 'type', 'string', true );

           
// Set remove custom settings query
           
$remove_query = 'DELETE FROM T_users__usersettings WHERE uset_name = "%s" AND uset_value != %s';
            if(
$type == 'sender_email' )
            {
// Remove custom sender emails
               
$DB->query( sprintf( $remove_query, 'notification_sender_email', $DB->quote( $Settings->get( 'notification_sender_email' ) ) ) );
            }
            elseif(
$type == 'sender_name' )
            {
// Remove custom sender names
               
$DB->query( sprintf( $remove_query, 'notification_sender_name', $DB->quote( $Settings->get( 'notification_sender_name' ) ) ) );
            }
            else
            {
// The customization param is not valid
               
debug_die('Invalid remove sender customization action!');
            }

           
$Messages->add( TB_('Customizations have been removed!' ), 'success' );
           
$redirect_to = param( 'redirect_to', 'url', regenerate_url( 'action' ) );
           
// Redirect so that a reload doesn't write to the DB twice:
           
header_redirect( $redirect_to );
           
/* EXITED */
           
break;

        case
'remove_report':
           
// Remove one report on user:

            // Check that this action request is not a CSRF hacked request:
           
$Session->assert_received_crumb( 'users' );

           
$reporter_ID = param( 'reporter_ID', 'integer', true );

           
// Remove the report from DB:
           
$DB->query( 'DELETE FROM T_users__reports
                    WHERE urep_target_user_ID = '
.$DB->quote( $edited_User->ID ).'
                      AND urep_reporter_ID = '
.$DB->quote( $reporter_ID ) );

           
$Messages->add( TB_('The report has been removed!'), 'success' );

           
// Redirect so that a reload doesn't write to the DB twice:
           
header_redirect( $admin_url.'?ctrl=user&user_tab=activity&user_ID='.$edited_User->ID );
           
/* EXITED */
           
break;

        case
'campaign':
           
// Select the recipients for email campaign:

           
check_user_perm( 'emails', 'edit', true );

           
// Memorize action param to keep newsletter mode on change filters:
           
memorize_param( 'action', 'string', true, $action );

           
$Messages->add( TB_('Please select new recipients for this email campaign.'), 'success' );

           
load_funcs( 'email_campaigns/model/_emailcampaign.funcs.php' );
            if( ! (
$edited_EmailCampaign = & get_session_EmailCampaign() ) )
            {    
// Initialize Email Campaign once and store in Session:

                // ID of Email Campaign is required and should be memorized:
               
param( 'ecmp_ID', 'integer', true );

               
// Get Email Campaign by ID:
               
$EmailCampaignCache = & get_EmailCampaignCache();
               
$edited_EmailCampaign = & $EmailCampaignCache->get_by_ID( $ecmp_ID );

               
// Save Email Campaign ID in Session:
               
$Session->set( 'edited_campaign_ID', $edited_EmailCampaign->ID );
            }

           
// Set users filter "Subscribed to":
           
set_param( 'newsletter', $edited_EmailCampaign->get( 'enlt_ID' ) );
           
set_param( 'filter', 'new' );
            break;

        case
'add_automation':
           
// Add selected users to automation:

            // Check that this action request is not a CSRF hacked request:
           
$Session->assert_received_crumb( 'users' );

           
// Check permission:
           
check_user_perm( 'options', 'view', true );

           
param( 'autm_ID', 'integer', true );
           
param( 'enlt_ID', 'integer', true );

           
$AutomationCache = & get_AutomationCache();
           
$Automation = & $AutomationCache->get_by_ID( $autm_ID );

           
load_funcs( 'email_campaigns/model/_emailcampaign.funcs.php' );

           
$added_users_num = $Automation->add_users( get_filterset_user_IDs(), array(
                   
'users_no_subs'   => param( 'users_no_subs', 'string', 'ignore' ),
                   
'users_automated' => param( 'users_automated', 'string', 'ignore' ),
                   
'users_new'       => param( 'users_new', 'string', 'ignore' ),
                   
'newsletter_IDs'  => $enlt_ID,
                ) );

           
$Messages->add( sprintf( TB_('%d users have been added or requeued for automation "%s"'), $added_users_num, $Automation->get( 'name' ) ), 'success' );

           
// Redirect so that a reload doesn't write to the DB twice:
           
header_redirect( $admin_url.'?ctrl=automations&action=edit&tab=users&autm_ID='.$Automation->ID, 303 ); // Will EXIT
            // We have EXITed already at this point!!
           
break;

        case
'update_tags':
           
// Add/Remove tag to /from selected users:

            // Check that this action request is not a CSRF hacked request:
           
$Session->assert_received_crumb( 'users' );

           
// Check permission:
           
check_user_perm( 'users', 'edit', true );

           
param( 'add_user_tags', 'string', '' );
           
param( 'remove_user_tags', 'string', '' );

           
load_funcs( 'email_campaigns/model/_emailcampaign.funcs.php' );

           
$UserCache = & get_UserCache();
           
$UserCache->clear();
           
$UserCache->load_list( get_filterset_user_IDs() );

           
$updated_users_num = 0;
            foreach(
$UserCache->cache as $filtered_User )
            {    
// Update tags of each filtered User:
               
$filtered_User->add_usertags( $add_user_tags );
               
$filtered_User->remove_usertags( $remove_user_tags );
                if(
$filtered_User->dbupdate() )
                {
                   
$updated_users_num++;
                }
            }

           
$Messages->add( sprintf( TB_('Tags of %d users have been updated'), $updated_users_num ), 'success' );

           
// Redirect so that a reload doesn't write to the DB twice:
           
header_redirect( '?ctrl=users', 303 ); // Will EXIT
            // We have EXITed already at this point!!
           
break;

        case
'update_status':
           
// Set account status of selected users:

            // Check that this action request is not a CSRF hacked request:
           
$Session->assert_received_crumb( 'users' );

           
// Check permission:
           
check_user_perm( 'users', 'edit', true );

           
param( 'account_status', 'string', '' );

           
load_funcs( 'email_campaigns/model/_emailcampaign.funcs.php' );

           
$UserCache = & get_UserCache();
           
$UserCache->clear();
           
$UserCache->load_list( get_filterset_user_IDs() );

           
// Try to obtain some serious time to do some serious processing (30 minutes)
           
set_max_execution_time( 1800 );

           
$updated_users_num = 0;
            foreach(
$UserCache->cache as $filtered_User )
            {    
// Update account status of each filtered User:
               
if( $filtered_User->ID == 1 )
                {    
// This is Admin user, Don't allow to change status:
                   
continue;
                }

                if(
$filtered_User->update_status_from_Request( true, $account_status ) )
                {
                   
$updated_users_num++;
                }
            }

           
$Messages->add( sprintf( TB_('Account status of %d users have been updated'), $updated_users_num ), 'success' );

           
// Redirect so that a reload doesn't write to the DB twice:
           
header_redirect( '?ctrl=users', 303 ); // Will EXIT
            // We have EXITed already at this point!!
           
break;

        case
'update_groups':
           
// Change group membership of selected users:

            // Check that this action request is not a CSRF hacked request:
           
$Session->assert_received_crumb( 'users' );

           
// Check permission:
           
check_user_perm( 'users', 'edit', true );

           
$primary_grp_ID = param( 'grp_ID', 'integer' );
           
$add_secondary_grp_ID = param( 'add_secondary_grp_ID', 'integer' );
           
$remove_secondary_grp_ID = param( 'remove_secondary_grp_ID', 'integer' );

           
load_funcs( 'email_campaigns/model/_emailcampaign.funcs.php' );

           
$GroupCache = & get_GroupCache();

            if( isset(
$primary_grp_ID ) )
            {
               
$primary_group = $GroupCache->get_by_ID( $primary_grp_ID );
            }

           
$UserCache = & get_UserCache();
           
$UserCache->clear();
           
$UserCache->load_list( get_filterset_user_IDs() );

           
$updated_primary_grp_num = 0;
           
$added_secondary_grp_num = 0;
           
$removed_secondary_grp_num = 0;
           
$updated_users_num = 0;

            foreach(
$UserCache->cache as $filtered_User )
            {    
// Update group membership of each filtered User:

               
$updated_group = false;

                if( (
$filtered_User->ID != 1 ) && isset( $primary_group ) && $primary_group->can_be_assigned() )
                {    
// This is Admin user, Don't allow to change status:
                   
$filtered_User->set_Group( $primary_group );
                   
$updated_primary_grp_num++;
                   
$updated_group = true;
                }

                if( isset(
$add_secondary_grp_ID ) || isset( $remove_secondary_grp_ID ) )
                {
                   
$secondary_grp_IDs = array();
                   
$filtered_User->old_secondary_groups = $filtered_User->get_secondary_groups();
                    foreach(
$filtered_User->secondary_groups as $secondary_Group )
                    {
                       
$secondary_grp_IDs[] = $secondary_Group->ID;
                    }

                    if( isset(
$add_secondary_grp_ID ) && ! in_array( $add_secondary_grp_ID, $secondary_grp_IDs ) )
                    {    
// User not yet a member of new secondary group:
                       
$new_secondary_group = $GroupCache->get_by_ID( $add_secondary_grp_ID, false, false );
                        if( isset(
$new_secondary_group ) && $new_secondary_group->can_be_assigned() )
                        {
                           
$secondary_grp_IDs[] = $add_secondary_grp_ID;
                           
$added_secondary_grp_num++;
                           
$updated_group = true;
                        }
                    }

                    if( isset(
$remove_secondary_grp_ID ) && ( ( $key = array_search( $remove_secondary_grp_ID, $secondary_grp_IDs ) ) !== false ) )
                    {    
// User is a member of secondary group to be removed:
                       
unset( $secondary_grp_IDs[$key] );
                       
$removed_secondary_grp_num++;
                       
$updated_group = true;
                    }

                   
$GroupCache = & get_GroupCache();
                   
$GroupCache->clear();
                   
// Set new groups which should be stored in DB:
                   
$filtered_User->secondary_groups = $GroupCache->load_list( $secondary_grp_IDs );
                }

                if(
$updated_group )
                {
                   
$filtered_User->dbupdate();
                   
$updated_users_num++;
                }
            }

           
$Messages->add( sprintf( TB_('Group membership of %d users have been updated'), $updated_users_num ), 'success' );

           
// Redirect so that a reload doesn't write to the DB twice:
           
header_redirect( '?ctrl=users', 303 ); // Will EXIT
            // We have EXITed already at this point!!
           
break;

        case
'merge':
           
// Select user for merging and Merge:
           
$merging_user_ID = param( 'merging_user_ID', 'integer', true, true );
           
$selected_user_ID = param( 'selected_user_ID', 'integer' );

            if(
$merging_user_ID == 1 )
            {    
// User #1 cannot be deleted so we should not allow to merge it as well:
                // Don't translate because this must not occurs:
               
debug_die( 'You can\'t merge User #1!' );
            }

           
// Check edit permissions:
           
$current_User->can_moderate_user( $merging_user_ID, true );

            if( empty(
$selected_user_ID ) )
            {    
// Inform to select a remaining account if it is not selected yet:
               
$Messages->add( sprintf( TB_('User data from account %s will be merged to the account you select below. Check a radio button and click the orange button at the bottom.'), get_user_identity_link( '', $merging_user_ID ) ), 'warning' );
            }
            else
            {    
// Check edit permissions for remaining user as well:
               
$current_User->can_moderate_user( $selected_user_ID, true );
            }

           
// The merging process is executed in the template below by function display_users_merging_process().
           
break;

        case
'delete_spammers':
           
// Delete selected users as spammers:

            // Check that this action request is not a CSRF hacked request:
           
$Session->assert_received_crumb( 'users' );

           
// Check permission:
           
check_user_perm( 'users', 'edit', true );

           
$users = explode( ',', param( 'users', 'string' ) );

           
// Set this param in order to delete the users as spammer:
           
set_param( 'deltype', 'spammer' );

           
$deleted_spam_logins = array();
           
$not_deleted_spam_logins = array();
           
$UserCache = & get_UserCache();
           
$delspam_Messages = new Messages();
            foreach(
$users as $u => $user_ID )
            {
                if( ! (
$deleted_spam_User = & $UserCache->get_by_ID( $user_ID, false, false ) ) )
                {    
// Skip if user is not found in DB by requested ID:
                   
continue;
                }
               
$deleted_spam_login = $deleted_spam_User->get( 'login' );
               
// Delete user as spammer:
               
if( $deleted_spam_User->dbdelete( $delspam_Messages ) )
                {    
// If user has been deleted:
                   
$deleted_spam_logins[] = $deleted_spam_login;
                }
                else
                {    
// If user cannot be deleted by some reason:
                   
$not_deleted_spam_logins[] = $deleted_spam_User->get_identity_link();
                }
            }

            if(
count( $deleted_spam_logins ) > 0 )
            {    
// Display a message if at least one spammer have been deleted:
               
$Messages->add( sprintf( TB_('Spammers %s have been deleted.'), implode( ', ', $deleted_spam_logins ) ), 'success' );
            }
            if(
count( $not_deleted_spam_logins ) > 0 )
            {    
// Display a message if at least one spammer have NOT been deleted:
               
$Messages->add( sprintf( TB_('Spammers %s could not been deleted.'), implode( ', ', $not_deleted_spam_logins ) ), 'error' );
            }

           
// Redirect so that a reload doesn't write to the DB twice:
           
header_redirect( '?ctrl=users'.( count( $not_deleted_spam_logins ) > 0 ? '&action=spammers' : '' ), 303 ); // Will EXIT
            // We have EXITed already at this point!!
           
break;

        case
'export':
           
// Export users group membership data into CSV file:

            // Check that this action request is not a CSRF hacked request:
           
$Session->assert_received_crumb( 'users' );

           
// Check permission:
           
check_user_perm( 'users', 'view', true );

           
load_class( 'users/model/_userlist.class.php', 'UserList' );
           
$UserList = new UserList( 'admin' );
           
$UserList->memorize = false;
           
$UserList->load_from_Request();
            if( empty(
$UserList->filters['users'] ) )
            {    
// No users to export:
               
header_redirect( $admin_url.'?ctrl=users' );
                break;
            }

           
$SQL_main_group = new SQL();
           
$SQL_main_group->SELECT( 'user_ID, user_login, grp_name, "primary" AS type' );
           
$SQL_main_group->FROM( 'T_users' );
           
$SQL_main_group->FROM_add( 'INNER JOIN T_groups ON user_grp_ID = grp_ID' );
           
$SQL_main_group->WHERE( 'user_ID IN ('.implode( ',', $UserList->filters['users'] ).') ' );
           
$SQL_sub_groups = new SQL();
           
$SQL_sub_groups->SELECT( 'user_ID, user_login, grp_name, "secondary" AS type' );
           
$SQL_sub_groups->FROM( 'T_users' );
           
$SQL_sub_groups->FROM_add( 'INNER JOIN T_users__secondary_user_groups ON sug_user_ID = user_ID' );
           
$SQL_sub_groups->FROM_add( 'INNER JOIN T_groups ON sug_grp_ID = grp_ID' );
           
$SQL_sub_groups->WHERE( 'sug_user_ID IN ('.implode( ',', $UserList->filters['users'] ).') ' );
           
$user_groups_sql = 'SELECT * FROM ( '.$SQL_main_group->get().' UNION '.$SQL_sub_groups->get().' ) AS users
                ORDER BY FIND_IN_SET( user_ID, "'
.implode( ',', $UserList->filters['users'] ).'" ), type';
           
$users = $DB->get_results( $user_groups_sql, ARRAY_A, 'Get users group membership data for export group data into CSV file' );

           
header_nocache();
           
header_content_type( 'text/csv' );
           
header( 'Content-Disposition: attachment; filename=user-groups.csv' );

            echo
get_csv_line( array( 'username', 'groupname', 'type' ) );

            foreach(
$users as $user )
            {
                unset(
$user['user_ID'] );
                echo
get_csv_line( $user );
            }
            exit;

        case
'export_users': // PRO-ONLY
            // Export users data into CSV file:

            // Restrict this feature for NOT PRO version:
           
check_pro();

           
// Check that this action request is not a CSRF hacked request:
           
$Session->assert_received_crumb( 'users' );

           
// Check permission:
           
check_user_perm( 'users', 'view', true );

           
// Do export:
           
load_funcs( 'pro_only/model/_pro_user.funcs.php' );
           
pro_export_users();
            exit;

        case
'csv': // PRO-ONLY
            // Check if we can display form to import users:
            // Restrict this feature for NOT PRO version:
           
check_pro();
            break;

        case
'import': // PRO-ONLY
            // Import new users:

            // Restrict this feature for NOT PRO version:
           
check_pro();

           
// Check that this action request is not a CSRF hacked request:
           
$Session->assert_received_crumb( 'users' );

           
// Check permission:
           
check_user_perm( 'users', 'edit', true );

           
// Do import:
           
load_funcs( 'pro_only/model/_pro_user.funcs.php' );
           
$import_operation = pro_import_users();

            if(
$import_operation === false )
            {    
// Some errors are exist, Stop the importing:
               
$action = 'csv';
                break;
            }
            else
            {
               
header_redirect( $admin_url.'?ctrl=users', 303 ); // Will EXIT
           
}
            break;

        case
'save_default_filters':
           
// Save default users list filters:

            // Check that this action request is not a CSRF hacked request:
           
$Session->assert_received_crumb( 'users' );

           
// Check permission:
           
check_user_perm( 'users', 'edit', true );

           
$filters = array();
            for(
$i = 1; $i <= 10; $i++ )
            {
               
$filter = param( 'filter_'.$i, 'string' );
                if( ! empty(
$filter ) && ! in_array( $filter, $filters ) )
                {
                   
$filters[] = $filter;
                }
            }

           
// Set new default users list filters:
           
$Settings->set( 'userlist_default_filters', implode( ',', $filters ) );
           
$Settings->dbupdate();

           
$Messages->add( TB_('Default filters have been updated for users list.'), 'success' );

           
// Redirect so that a reload doesn't write to the DB twice:
           
header_redirect( $admin_url.'?ctrl=users&filter=new&users_filter_preset=advanced', 303 ); // Will EXIT
            // We have EXITed already at this point!!
           
break;
    }
}

// Used for autocomplete user fields in filter "Specific criteria" or to highlight user level cell on change
require_js_defer( '#jqueryUI#' );
require_css( '#jqueryUI_css#' );

// We might delegate to this action from above:
/*if( $action == 'edit' )
{
    $Plugins->trigger_event( 'PluginUserSettingsEditAction', $tmp_params = array( 'User' => & $edited_User ) );
    $Session->delete( 'core.changepwd.request_id' ); // delete the request_id for password change request (from /htsrv/login.php)
}*/


$AdminUI->breadcrumbpath_init( false );  // fp> I'm playing with the idea of keeping the current blog in the path here...
$AdminUI->breadcrumbpath_add( TB_('Users'), '?ctrl=users' );
if(
$tab == 'stats' )
{    
// Users stats
   
$AdminUI->breadcrumbpath_add( TB_('Stats'), '?ctrl=users&amp;tab=stats' );
   
// Init jqPlot charts
   
init_jqplot_js();

   
// Set an url for manual page:
   
$AdminUI->set_page_manual_link( 'user-stats' );
}
else
{    
// Users list
   
init_tokeninput_js();
   
// Load jQuery QueryBuilder plugin files for user list filters:
   
init_querybuilder_js( 'rsc_url' );

   
$entries = array(
       
'list' => array(
           
'text' => TB_('List'),
           
'href' => '?ctrl=users' ),
       
'duplicates' => array(
           
'text' => TB_('Find duplicates'),
           
'href' => '?ctrl=users&amp;tab3=duplicates' ) );
   
$AdminUI->add_menu_entries( array( 'users', 'users' ), $entries );

    switch(
$tab3 )
    {
        case
'duplicates':
           
$AdminUI->breadcrumbpath_add( TB_('List'), '?ctrl=users&amp;tab3='.$tab3 );
           
$AdminUI->set_page_manual_link( 'users-find-duplicates' );
            break;

        default:
           
// Initialize user tag input

           
$AdminUI->breadcrumbpath_add( TB_('List'), '?ctrl=users' );
           
$AdminUI->top_block = get_user_quick_search_form();
            if(
check_user_perm( 'users', 'moderate' ) )
            {    
// Include to edit user level
               
require_js_defer( 'customized:jquery/jeditable/jquery.jeditable.js', 'rsc_url' );
            }
           
load_funcs( 'regional/model/_regional.funcs.php' );

           
// Set an url for manual page:
           
$AdminUI->set_page_manual_link( 'users-users' );
    }

}

// Initialize date picker
init_datepicker_js();

if(
$display_mode != 'js')
{
   
// Display <html><head>...</head> section! (Note: should be done early if actions do not redirect)
   
$AdminUI->disp_html_head();

   
// Display title, menu, messages, etc. (Note: messages MUST be displayed AFTER the actions)
   
$AdminUI->disp_body_top();
}

/*
 * Display appropriate payload:
 */
switch( $action )
{
    case
'nil':
       
// Display NO payload!
       
break;

    case
'csv': // PRO-ONLY
        // Display form to import users:
       
$AdminUI->disp_view( 'users/views/_user_import.form.php' );
        break;

    case
'delete':
       
$deltype = param( 'deltype', 'string', '' ); // spammer

       
$AdminUI->disp_payload_begin();

       
// We need to ask for confirmation:
       
$fullname = $edited_User->dget( 'fullname' );
       
$del_user_name = empty( $fullname ) ? $edited_User->dget( 'login' ) : '"'.$fullname.'" ['.$edited_User->dget( 'login' ).']';
       
$msg = ( $deltype == 'spammer' ) ? TB_('Delete SPAMMER %s?') : TB_('Delete user %s?');
       
$msg = sprintf( $msg, $del_user_name );

       
$confirm_messages = array();
        if(
$deltype == 'spammer' )
        {    
// Display the notes for spammer deleting:
           
$confirm_messages[] = array( TB_('Note: this will also delete private messages sent/received by this user.'), 'note' );
           
$confirm_messages[] = array( TB_('Note: this will also delete comments made by this user.'), 'note' );
           
$confirm_messages[] = array( TB_('Note: this will also delete files uploaded by this user.'), 'note' );
           
$confirm_messages[] = array( '<strong>'.sprintf( TB_('Note: the email address %s will be banned from registering again.'), '<code>'.$edited_User->get( 'email' ).'</code>' ).'</strong>', 'note' );
        }
        else
        {    
// Display the notes for standard deleting:
           
$confirm_messages[] = array( TB_('Note: this will <b>not</b> automatically delete private messages sent/received by this user. However, this will delete any new orphan private messages (which no longer have any existing sender or recipient).')
                .
'<br /><label><input type="checkbox" name="force_delete_messages" value="1" /> '.TB_('Force deleting all private messages sent/received by this user.').'</label>', 'note' );
           
$confirm_messages[] = array( TB_('Note: this will <b>not</b> delete comments made by this user. Instead it will transform them from member to visitor comments.')
                .
'<br /><label><input type="checkbox" name="force_delete_comments" value="1" /> '.TB_('Force deleting all comments made by this user.').'</label>', 'note' );
           
$confirm_messages[] = array( TB_('Note: this will <b>not</b> delete files uploaded by this user outside of the user root. Instead the creator ID of these files will be set to NULL.')
                .
'<br /><label><input type="checkbox" name="force_delete_files" value="1" /> '.TB_('Force deleting all files uploaded by this user.').'</label>', 'note' );
        }

       
// Find other users with the same email address
       
$message_same_email_users = find_users_with_same_email( $edited_User->ID, $edited_User->get( 'email' ), TB_('Note: this user has the same email address (%s) as: %s') );
        if(
$message_same_email_users !== false )
        {
           
$confirm_messages[] = array( $message_same_email_users, 'note' );
        }

       
// Add a checkbox on deletion form
       
$delete_form_params = array();
        if(
$Settings->get( 'reportpm_enabled' ) )
        {
// If this feature is enabled
           
$user_count_reports = count( get_user_reported_user_IDs( $edited_User->ID ) );
            if(
$user_count_reports > 0 )
            {
// If the user has been reported at least one time
               
$delete_form_params['before_submit_button'] = '<p><label>'
                       
.'<input type="checkbox" id="send_reportpm" name="send_reportpm" value="1"'.( $deltype == 'spammer' ? ' checked="checked"' : '' ).' /> '
                       
.sprintf( TB_('Send an info message to %s users who reported this account.'), $user_count_reports )
                    .
'</label></p>'
                   
.'<p><label>'
                       
.'<input type="checkbox" id="increase_spam_score" name="increase_spam_score" value="1"'.( $deltype == 'spammer' ? ' checked="checked"' : '' ).' /> '
                       
.sprintf( TB_('Increase spam fighter score for the %s users who reported this account.'), $user_count_reports )
                    .
'</label></p>';
            }
        }

       
$edited_User->confirm_delete( $msg, 'user', $action, get_memorized( 'action' ), $confirm_messages, $delete_form_params );

        if(
$deltype == 'spammer' )
        {    
// Display user activity lists:
           
$user_tab = 'activity';
           
$AdminUI->disp_view( 'users/views/_user_activity.view.php' );
        }
        else
        {    
// Display user identity form:
           
$AdminUI->disp_view( 'users/views/_user_identity.form.php' );
        }
       
$AdminUI->disp_payload_end();

       
// Init JS for user reporting
       
echo_user_report_window();
        break;

    case
'automation':
       
// Display a form to add users selection to automation:

        // Do not append Debuglog & Debug JSlog to response!
       
$debug = false;
       
$debug_jslog = false;

       
$AdminUI->disp_payload_begin();

       
load_funcs( 'email_campaigns/model/_emailcampaign.funcs.php' );
       
$AdminUI->disp_view( 'users/views/_user_list_automation.form.php' );

       
$AdminUI->disp_payload_end();
        break;

    case
'edit_tags':
       
// Display a form to add/remove tags to/from users selection:

        // Do not append Debuglog & Debug JSlog to response!
       
$debug = false;
       
$debug_jslog = false;

       
$AdminUI->disp_payload_begin();

       
$AdminUI->disp_view( 'users/views/_user_list_tags.form.php' );

       
$AdminUI->disp_payload_end();
        break;

    case
'set_status':
       
// Display a form to set user account status:

        // Do not append Debuglog & Debug JSlog to response!
       
$debug = false;
       
$debug_jslog = false;

       
$AdminUI->disp_payload_begin();

       
$AdminUI->disp_view( 'users/views/_user_list_status.form.php' );

       
$AdminUI->disp_payload_end();
        break;

    case
'change_groups':
       
// Display a form to set user account status:

        // Do not append Debuglog & Debug JSlog to response!
       
$debug = false;
       
$debug_jslog = false;

       
$AdminUI->disp_payload_begin();

       
$AdminUI->disp_view( 'users/views/_user_list_groups.form.php' );

       
$AdminUI->disp_payload_end();
        break;

    case
'spammers':
       
memorize_param( 'action', 'string', '', $action );
       
$AdminUI->disp_payload_begin();
       
$AdminUI->disp_view( 'users/views/_user_list_spammers.view.php' );
       
$AdminUI->disp_payload_end();
        break;

    case
'promote':
    default:
       
// Display user list:
        // NOTE: we don't want this (potentially very long) list to be displayed again and again)
       
$AdminUI->disp_payload_begin();
        if(
$tab == 'stats' )
        {
           
$AdminUI->disp_view( 'users/views/_user_stats.view.php' );
        }
        else
        {
            switch(
$tab3 )
            {
                case
'duplicates':
                   
$AdminUI->disp_view( 'users/views/_duplicate_email_user_list.view.php' );
                    break;

                default:
                   
$AdminUI->disp_view( 'users/views/_user_list.view.php' );
            }

        }
       
$AdminUI->disp_payload_end();
}

if(
$display_mode != 'js')
{
   
// Display body bottom, debug info and close </html>:
   
$AdminUI->disp_global_footer();
}
?>