body<= '/community/manage.bml', 'text' => $ML{'.manage2'}, }); # get remote my $remote = LJ::get_remote(); unless ($remote) { $ret .= ""; return $ret; } my $cname = $GET{'comm'}; return BML::redirect("$LJ::SITEROOT/community/manage.bml") unless $cname; # get $c object my $c = LJ::load_user($cname); unless ($c) { $ret .= ""; return $ret; } my $cid = $c->{'userid'}; # is $remote an admin? unless (LJ::can_manage_other($remote, $c)) { $ret .= " LJ::ljuser($cname, { 'type' => 'C' }) }); $ret .= " p?>"; return $ret; } my @allattribs = ('member', 'post', 'preapprove', 'moderate', 'admin'); my %attrshort = ( X => 'member', P => 'post', N => 'preapprove', M => 'moderate', A => 'admin'); my %attrshort_r = ( map { $attrshort{$_} => $_ } keys %attrshort ); # reversed # saving a form submission if ($POST{'action:update'}) { # validate form auth return "" unless LJ::check_form_auth(); my @userids = split(',', $POST{'ids'}); my @saveattribs = split(',', $POST{'attribs'}); # now we need to create our 'was' list my %was; # ( userid => { attrib => 1; } ) my %users; # ( userid => username ) foreach my $row (split ';', $POST{was}) { # UID:UNAME:MNPX;UID:UNAME:MX;UID:UNAME:AM # if this row matches... if ($row =~ /^(\d+):(\w+):(\w+)$/) { my ($uid, $name, $attrs) = ($1, $2, $3); $uid += 0; next unless $uid && $name && $attrs; # split attrs and setup $was{$uid}->{$attrshort{$_}} = 1 foreach split '', $attrs; $users{$uid} = $name; } } # invite new users my @to_add; my @add_errors; foreach my $num (1..5) { $POST{"add_$num"} = LJ::trim($POST{"add_$num"}); next unless $POST{"add_$num"} =~ /^\w+$/; my $target = LJ::load_user($POST{"add_$num"}); unless ($target) { push @add_errors, BML::ml('.error.nouser', { 'user' => $POST{"add_$num"} }); next; } unless ($target->{statusvis} eq 'V') { push @add_errors, BML::ml('.error.notactive', { 'user' => LJ::ljuser($POST{"add_$num"}) }); next; } my @attr = grep { defined $POST{"add_${num}_$_"} } @saveattribs; unless (@attr) { push @add_errors, BML::ml('.error.noattr', { 'user' => LJ::ljuser($POST{"add_$num"}, { 'type' => $target->{'journaltype'} }) }); next; } unless ($target->{'journaltype'} eq 'P') { push @add_errors, BML::ml('.error.invaliduser', { 'user' => LJ::ljuser($POST{"add_$num"}, { 'type' => $target->{'journaltype'} }) }); next; } if (grep { $target->{'userid'} == $_ } @userids) { push @add_errors, BML::ml('.error.alreadyadded', { 'user' => LJ::ljuser($POST{"add_$num"}, { 'type' => $target->{'journaltype'} }) }); next; } # insert authactions row push @to_add, [ $target, \@attr ]; } return LJ::bad_input(@add_errors) if @add_errors; # now do the additions if any were needed my @fail; my @invited; if (@to_add) { foreach my $row (@to_add) { # good, let's extend an invite to this person my ($target, $attrs) = @$row; if (LJ::send_comm_invite($target, $c, $remote, $attrs)) { push @invited, $row; } else { push @fail, [ $target, LJ::last_error_code() ]; } } } if (@fail) { my @bad; foreach (@fail) { if ($_->[1] eq 'comm_user_has_banned') { push @bad, BML::ml('.error.adding', { user => LJ::ljuser($_->[0], { type => 'P' }) }); } elsif ($_->[1] eq 'comm_invite_limit') { push @bad, BML::ml('.error.limit', { user => LJ::ljuser($_->[0], { type => 'P' }) }); } else { push @bad, BML::ml('.error.unknown', { user => LJ::ljuser($_->[0], { type => 'P' }) }); } } return LJ::bad_input(@bad); } # initialize lists of users to update and delete # keyed on attribute type my %add = (); my %delete = (); foreach (@allattribs) { $add{$_} = {}; $delete{$_} = {}; } # need a db handle now my $dbh = LJ::get_db_writer(); # if we have $other_maints, then there are maintainers not in our # current view, so they will not be modified, so the user can delete # all maintainers from the current view my $in = join(',', map { $dbh->quote($_) } @userids); my $other_maints = $dbh->selectrow_array("SELECT COUNT(*) FROM reluser " . "WHERE userid=? AND type='A' " . "AND targetid NOT IN ($in)", undef, $cid); # users already in community my $maints = 0; my (%addr, %delr); # store additions and removals sorted by userid foreach my $id (@userids) { $id = $id + 0; my $str; foreach (@allattribs) { if ($POST{"edit_${id}_$_"}) { unless ($was{$id}->{$_}) { $add{$_}->{$id} = 1; $addr{$id}->{$_} = 1; } } else { if ($was{$id}->{$_}) { $delete{$_}->{$id} = 1; $delr{$id}->{$_} = 1; } } } $maints++ if $POST{"edit_${id}_admin"}; } # can't remove ALL maintainers, give them an error so they can # go back and decide who to keep if (! $other_maints && $maints < 1) { $ret .= " 'C' }) . ", must have at least one maintainer. " . "Please " . "go back and add a maintainer. p?>"; return $ret; } # delete members if (%{$delete{'member'}}) { # TAG:FR:bml_comm_members:del_members LJ::remove_friend($cid, [ keys %{$delete{'member'}} ]); } # log maintainer deletions foreach my $uid (keys %{$delete{admin} || {}}) { $c->log_event('maintainer_remove', { actiontarget => $uid, remote => $remote }); } # delete other rel edges LJ::clear_rel_multi( (map { [$cid, $_, 'A'] } keys %{$delete{admin} || {}}), (map { [$cid, $_, 'P'] } keys %{$delete{post} || {}}), (map { [$cid, $_, 'M'] } keys %{$delete{moderate} || {}}), (map { [$cid, $_, 'N'] } keys %{$delete{preapprove} || {}}), ); # perform additions my @msgs; if (%{$add{'member'}}) { foreach my $id (keys %{$add{'member'}}) { next if $was{$id}->{'member'}; my $u = LJ::load_userid($id); if (LJ::u_equals($u, $remote)) { # you're allowed to add yourself as member LJ::join_community($remote, $c); } else { if (LJ::send_comm_invite($u, $c, $remote, [ 'member' ])) { # if it succeeded, push the reinvited information push @msgs, BML::ml('.reinvited2', { user => LJ::ljuser($u, { type => 'P' }), aopts => "href='$LJ::SITEROOT/manage/invites.bml'" }); } } } } # log maintainer additions foreach my $uid (keys %{$add{admin} || {}}) { $c->log_event('maintainer_add', { actiontarget => $uid, remote => $remote }); } # set rels in db/memcache LJ::set_rel_multi( (map { [$cid, $_, 'A'] } keys %{$add{admin} || {}}), (map { [$cid, $_, 'P'] } keys %{$add{post} || {}}), (map { [$cid, $_, 'M'] } keys %{$add{moderate} || {}}), (map { [$cid, $_, 'N'] } keys %{$add{preapprove} || {}}), ); # create some other messages my %done; # keep track of who we've done foreach my $id (keys %addr, keys %delr) { next if $done{$id}++; my ($str, @astr, @dstr); push @astr, $ML{"/manage/invites.bml.label.$_"} foreach keys %{$addr{$id} || {}}; push @dstr, $ML{"/manage/invites.bml.label.$_"} foreach keys %{$delr{$id} || {}}; $str .= "