# FILE: adm-mod.pl
# DESCRIPTION: Moderator Manager Interfaces
#-------------------------------------------------------------------------------
# DISCUS COPYRIGHT NOTICE
#
# Discus is copyright (c) 2002 by DiscusWare, LLC, all rights reserved.
# The use of Discus is governed by the Discus License Agreement which is
# available from the Discus WWW site at:
#    http://www.discusware.com/discus/license
#
# Pursuant to the Discus License Agreement, this copyright notice may not be
# removed or altered in any way.
#-------------------------------------------------------------------------------

use strict;
use vars qw($GLOBAL_OPTIONS $DCONF $PARAMS);

###
### MODERATOR_admin
###
### Controls Moderator Manager and all of its functions
###

sub MODERATOR_admin {
	my ($FORMref) = @_;
	dreq("template");
	my $result = check_password($FORMref->{username}, undef, { type_required => 'moderator' }, $FORMref->{'COOKIE'});
	bad_login( { bad_username => 1 } ) if scalar(@{ $result }) == 0;
	bad_login( { superuser_required => 1 } ) if $result->[0]->{user} ne $DCONF->{superuser};
	moderator_manager($FORMref, $result) if $FORMref->{'action'} eq "mod_mgr";
	if ($FORMref->{'action'} eq "mod_demote") {
		dreq("promote-PRO");
		promote_moderator_manager_action($FORMref, $result);
	}
	if ($FORMref->{'action'} eq "mod_mgmt") {
		my $sa = $FORMref->{SELECTION_action};
		my $sw = $FORMref->{SELECTION_who};
		my $modsel = mod_act_setup($sa, $sw, $FORMref->{MARK});
		moderator_topic_assign_screen($modsel, $FORMref, $result) if $sa eq "t";
		moderator_group_assign_screen($modsel, $FORMref, $result) if $sa eq "g";
		if ($sa eq "u") {
			dreq("promote-PRO");
			promote_moderator_manager($modsel, $FORMref, $result);
		}
		moderator_manager($FORMref, $result, { count => delete_moderator($modsel), what => 1 }) if $sa eq "d";
		moderator_edit_another_moderator($FORMref, $result, $modsel) if $sa eq "e";
		moderator_mailing_list($FORMref, $result, $modsel) if $sa eq "l";
		error_message("Moderator Management Error", "Error code MM001: Invalid Query", 0, 1);
	}
	if ($FORMref->{'action'} eq "mod_add") {
		my %h = map { $_ => $FORMref->{$_} } ('user', 'pass1', 'email', 'pass2', 'fullname');
		$h{'status'} = 9;
		dreq("fcn-acct");
		my ($success, $failed) = add_account( [ \%h ], { 'database' => 'passwd' });
		error_message("Add moderator failed!", "Check that the username is not already taken.", 0, 1) if scalar(@{$success}) == 0;
		$FORMref->{'mod'} = $h{'user'};
		$FORMref->{'menu'} = 1;
		moderator_manager($FORMref, $result, { what => 3, count => scalar(@{ $success }) });
	}
	if ($FORMref->{action} eq "mod_grp") {
		moderator_group_assign($FORMref, $result);
		my %l = map { $_, 1 } split(/,/, $FORMref->{affect});
		moderator_group_assign_screen(\%l, $FORMref, 2);
#		moderator_manager($FORMref, $result, { what => 4 } );
	}
	if ($FORMref->{action} eq "mod_priv") {
		moderator_topic_assign($FORMref, $result);
		moderator_manager($FORMref, $result, { what => 5 } );
	}
	if ($FORMref->{action} eq "mod_edit_save") {
		dreq("adm-user");
		my $r = user_edit_save_someone_else($FORMref, $result, "passwd");
		moderator_edit_another_moderator($FORMref, $result, undef, undef, {editsave => 1}, $r);
	}
	if ($DCONF->{pro} && $FORMref->{action} eq "mod_notify") {
		dreq("fcn-user-PRO");
		my $emhash = {};
		$emhash->{username} = $FORMref->{affect};
		$emhash->{action} = "set_str";
		$emhash->{new_str} = $FORMref->{group};
		new_registrations_email_moderators_config_write([$emhash]);
		moderator_group_assign_screen({ $FORMref->{affect} => 1 }, $FORMref, 1);
	}
}

###
### moderator_mailing_list
###
### Generates a mailing list of all selected moderators
###

sub moderator_mailing_list {
	my ($FORMref, $result, $w) = @_;
	dreq("authpass");
	my $Z = read_account_file("passwd", $w, { returnformat => "single_array" });
	my %f = map { $_->{email}, 1 } @{$Z};
	my $subst = {};
	my @z = map { { email => $_ } } sort keys %f;
	$subst->{addresses} = \@z;
	screen_out("emlist", $subst);
}

###
### moderator_edit_another_moderator
###
### Edit the profile of a moderator
###

sub moderator_edit_another_moderator {
	my ($FORMref, $result, $w, $subst_in, $stuff, $res) = @_;
	dreq("adm-user");
	my $subst = defined $subst_in ? $subst_in : {};
	$subst = user_edit_someone_else($FORMref, $result, $w, $subst, $stuff, $res, "passwd");
	screen_out("profile", $subst);
}

###
### delete_moderator
###
### Removes one or more moderators, and all of their privileges too
###

sub delete_moderator {
	my ($deletemod) = @_;
	dreq("fcn-acct", "fcn-grp", "fcn-priv");
	my ($success, $failure) = delete_account($deletemod, undef, "passwd");
	write_group_file( [ { group => "*", moderator => join(",", keys(%{ $deletemod })), action => "del_mod" } ] );
	write_privilege_file( [ { topic => "*", moderator => join(",", keys(%{ $deletemod })), action => "del_mod" } ] );
	return scalar(@{ $success });
}

###
### mod_act_setup
###
### Identifies marked moderators and removes superuser (who can't be deleted or
### otherwise acted upon from this screen)
###

sub mod_act_setup {
	my ($action, $sw, $mark) = @_;
	my %z = $sw eq '*' ? map {$_, 1} split(/,/, $mark) : map { $_, 1 } ($sw);		
	delete $z{$DCONF->{superuser}} if $action ne 'l';
	error_message("Moderator Action Error", "You did not select any moderators!  Remember that you cannot delete or edit the board administrator ($DCONF->{superuser}).", 0, 1) if scalar(keys(%z)) == 0;
	return \%z;
}

###
### moderator_manager
###
### Moderator Manager interface

sub moderator_manager {
	my ($FORMref, $result, $stuff) = @_;
	my $subst = {};
	$subst->{stuff} = $stuff;
	my $j = read_account_file("passwd", undef, { returnformat => "single_array" });
	my @j = sort { $a->{user} cmp $b->{user} } @{$j};
	$subst->{'moderators'} = \@j;
	$subst->{'general'}->{'username'} = $result->[0]->{user};
	$subst->{'general'}->{'menu'} = $FORMref->{'menu'};
	$subst->{'general'}->{'url'} = "$PARAMS->{cgiurl}?action=mod_mgr&username=$result->[0]->{user}";
	screen_out("mdrtrmgr", $subst);
}

###
### moderator_group_assign
###
### Assigns groups to selected moderators
###

sub moderator_group_assign {
	my ($FORMref) = @_;
	dreq("fcn-grp");
	my $grpfile = read_group_file();
	my @actions = ();
	my %q = map { $_, 1 } split(/,/, $FORMref->{group});
	foreach my $grp (@{ $grpfile->{group_list} }) {
		if ($q{$grp} == 1) {
			push (@actions, { action => "add_mod", group => $grp, moderator => $FORMref->{'affect'} });
		} else {
			push (@actions, { action => "del_mod", group => $grp, moderator => $FORMref->{'affect'} });
		}
	}
	write_group_file(\@actions);
}

###
### moderator_group_assign_screen
###
### Presents group selection screen for moderators
###

sub moderator_group_assign_screen {
	my ($groupmod, $FORMref, $flag) = @_;
	dreq("fcn-grp");
	my $k = scalar(keys(%{ $groupmod }));
	my $u = $k == 1 ? (keys(%{ $groupmod }))[0] : "";
	my $group_file = read_group_file();
	my @groups = ();
	foreach my $group_name (@{ $group_file->{group_list} }) {
		my $i = {}; my $c = 0;
		$i->{name} = $group_name;
		foreach my $mod (keys(%{ $groupmod })) {
			$c += $group_file->{by_grp}->{$group_name}->{$mod};
		}
		$i->{checked} = ($c >= scalar(keys(%{ $groupmod })) ? 1 : 0);
		push @groups, $i;
	}
	@groups = sort { lc($a->{name}) cmp lc($b->{name}) } @groups;
	my $subst = {};
	$subst->{general}->{mods} = $k;
	$subst->{general}->{moduser} = $u;
	$subst->{general}->{username} = $DCONF->{superuser};
	$subst->{groups} = \@groups;
	$subst->{general}->{affect} = join(",", keys(%{ $groupmod }));
	if ($DCONF->{pro} && $GLOBAL_OPTIONS->{capable} && scalar(keys(%{ $groupmod })) == 1) {
		dreq("selfreg-PRO", "fcn-user-PRO");
		my $x = read_selfreg_file();
		my @grps = ();
		my $hash = new_registrations_email_moderators_config_read(0, $group_file);
		foreach my $group (@groups) {
			my $group_name = $group->{name};
			my $param = $x->{param}->{$group_name}->{param};
			if ($param == 2) {
				$group->{notify_checked} = 1 if $hash->{$u}->{groups}->{$group_name};
				$group->{notify_enabled} = 1;
			}
		}
		my @mod = grep { $_->{notify_enabled} == 1 } @groups;
		$subst->{groups2} = \@mod;
		$subst->{general}->{queuemail} = 1 if scalar @mod;
	}
	$subst->{general}->{saved_flag} = $flag;
	screen_out("modgrpas", $subst);
}

###
### moderator_topic_assign
###
### Assigns topics to selected moderators
###

sub moderator_topic_assign {
	my ($FORMref) = @_;
	dreq("fcn-priv");
	my $topics = board_topics();
	my @actions = ();
	my %q = map { $_, 1 } split(/,/, $FORMref->{topic});
	foreach my $tpc (@{ $topics }) {
		next if $tpc->{type} == 2;
		my $grp = $tpc->{number};
		if ($q{$grp} == 1) {
			push @actions, { action => "add_mod", topic => $grp, moderator => $FORMref->{'affect'} };
		} else {
			push @actions, { action => "del_mod", topic => $grp, moderator => $FORMref->{'affect'} };
		}
	}
	write_privilege_file(\@actions);
}


###
### moderator_topic_assign_screen
###
### Presents topic selection screen for moderators
###

sub moderator_topic_assign_screen {
	my ($moderators, $FORMref, $result) = @_;
	dreq("fcn-priv");
	my $k = scalar(keys(%{ $moderators }));
	my $u = $k == 1 ? (keys(%{ $moderators }))[0] : "";
	my @corrective_actions = ();
	my $topics = board_topics();
	my $privileges_in = read_privilege_file();
	my @topic_output = ();
	foreach my $topic (@{ $topics }) {
		next if $topic->{type} == 2;
		if (! defined $privileges_in->{by_topic}->{ $topic->{number} }) {
			push (@corrective_actions, { action => 'add_topic', topic => $topic->{number}, moderator => 'admin' });
			$privileges_in->{by_topic}->{ $topic->{number} }->{$DCONF->{superuser}} = 1;
		}
		my $i = {}; my $c = 0;
		$i->{number} = $topic->{number};
		foreach my $mod (keys(%{ $moderators })) {
			$c += $privileges_in->{by_topic}->{$topic->{number}}->{$mod};
		}
		$i->{checked} = ($c >= scalar(keys(%{ $moderators })) ? 1 : 0);
		$i->{name} = $topic->{name};
		push @topic_output, $i;
	}
	write_privilege_file(\@corrective_actions) if scalar(@corrective_actions);
	my $subst = {};
	$subst->{general}->{mods} = $k;
	$subst->{general}->{moduser} = $u;
	$subst->{general}->{username} = $result->[0]->{user};
	$subst->{topics} = \@topic_output;
	$subst->{general}->{affect} = join(",", keys(%{ $moderators }));
	screen_out("modpriv", $subst);
}

1;
