webgui/lib/WebGUI/Account/FriendManager.pm
Scott Walters 54ae754ebe Repeat ampli's fix (described below) for other occurances on the site.
``The Save buttons in the two first steps didn't work in Chrome.
    According to a hint in the YUI Button documentation about a problem in using
    "submit" as a value of the name attribute, I changed submit button name
    in the two first steps from "submit" to "send".  This solved the problem.''
2011-06-29 19:13:18 -04:00

410 lines
14 KiB
Perl

package WebGUI::Account::FriendManager;
use strict;
use WebGUI::Exception;
use WebGUI::Friends;
use WebGUI::International;
use WebGUI::Pluggable;
use Tie::IxHash;
use base qw/WebGUI::Account/;
use List::MoreUtils qw/uniq/;
use JSON qw(from_json to_json);
=head1 NAME
Package WebGUI::Account::FriendManager
=head1 DESCRIPTION
Allow friends to be assigned to one another instead of the usual social
networking.
The style and layout settings are always inherited from the main Account
module.
=head1 SYNOPSIS
use WebGUI::Account::FriendManager;
=head1 METHODS
These methods are available from this class:
=cut
#-------------------------------------------------------------------
=head2 canView ( )
Returns whether or not the user can view the the tab for this module
=cut
sub canView {
my $self = shift;
my $session = $self->session;
return $session->user->isInGroup($session->setting->get('groupIdAdminFriends'));
}
#-------------------------------------------------------------------
=head2 getLayoutTemplateId ( )
Returns the template Id for the account layout. See L<WebGUI::Account::getLayoutTemplateId>.
=cut
sub getLayoutTemplateId {
my $self = shift;
return $self->session->setting->get("fmLayoutTemplateId") || $self->SUPER::getLayoutTemplateId;
}
#-------------------------------------------------------------------
=head2 getStyleTemplateId ( )
Returns the template Id for the main style. See L<WebGUI::Account::getStyleTemplateId>.
=cut
sub getStyleTemplateId {
my $self = shift;
return $self->session->setting->get("fmStyleTemplateId") || $self->SUPER::getStyleTemplateId;
}
#-------------------------------------------------------------------
=head2 editSettingsForm ( )
Creates form elements for the settings page custom to this account module.
=cut
sub editSettingsForm {
my $self = shift;
my $session = $self->session;
my $i18n = WebGUI::International->new($session,'Account_FriendManager');
my $f = WebGUI::FormBuilder->new($session);
$f->addField( "template",
name => "fmStyleTemplateId",
value => $self->getStyleTemplateId,
namespace => "style",
label => $i18n->get("style template label"),
hoverHelp => $i18n->get("style template hoverHelp"),
);
$f->addField( "template",
name => "fmLayoutTemplateId",
value => $self->getLayoutTemplateId,
namespace => "Account/Layout",
label => $i18n->get("layout template label"),
hoverHelp => $i18n->get("layout template hoverHelp"),
);
$f->addField( "group",
name => "groupIdAdminFriends",
value => $session->setting->get('groupIdAdminFriends'),
label => $i18n->get("setting groupIdAdminFriends label"),
hoverHelp => $i18n->get("setting groupIdAdminFriends hoverHelp"),
);
$f->addField( "group",
name => "groupsToManageFriends",
value => $session->setting->get('groupsToManageFriends'),
multiple => 1,
size => 5,
label => $i18n->get("groupsToManageFriends label"),
hoverHelp => $i18n->get("groupsToManageFriends hoverHelp"),
defaultValue => [2,3],
);
$f->addField( "template",
name => "fmViewTemplateId",
value => $self->session->setting->get("fmViewTemplateId"),
namespace => "Account/FriendManager/View",
label => $i18n->get("view template label"),
hoverHelp => $i18n->get("view template hoverHelp"),
);
$f->addField( "template",
name => "fmEditTemplateId",
value => $self->session->setting->get("fmEditTemplateId"),
namespace => "Account/FriendManager/Edit",
label => $i18n->get("edit template label"),
hoverHelp => $i18n->get("edit template hoverHelp"),
);
$f->addField( "yesNo",
name => "overrideAbleToBeFriend",
value => $self->session->setting->get("overrideAbleToBeFriend"),
label => $i18n->get("override abletobefriend label"),
hoverHelp => $i18n->get("override abletobefriend hoverHelp"),
);
return $f;
}
#-------------------------------------------------------------------
=head2 editSettingsFormSave ( )
Save
=cut
sub editSettingsFormSave {
my $self = shift;
my $session = $self->session;
my $setting = $session->setting;
my $form = $session->form;
$setting->set( "fmStyleTemplateId", $form->process( "fmStyleTemplateId", "template" ) );
$setting->set( "fmLayoutTemplateId", $form->process( "fmLayoutTemplateId", "template" ) );
$setting->set( "fmViewTemplateId", $form->process( "fmViewTemplateId", "template" ) );
$setting->set( "fmEditTemplateId", $form->process( "fmEditTemplateId", "template" ) );
$setting->set( "groupsToManageFriends", $form->process( "groupsToManageFriends", "group" ) );
$setting->set( "groupIdAdminFriends", $form->process( "groupIdAdminFriends", "group" ) );
$setting->set( "overrideAbleToBeFriend", $form->process( "overrideAbleToBeFriend", "yesNo" ) );
}
#-------------------------------------------------------------------
=head2 www_editFriends ( )
Edit the friends for a user. Uses the form variable userId, to determine which user.
Only users in the managed groups are shown. Group inheritance is supported, but
only for WebGUI defined groups.
=cut
sub www_editFriends {
my $self = shift;
my $session = $self->session;
my $form = $session->form;
my $userId = shift || $form->get('userId', 'guid');
my $user = WebGUI::User->new($session, $userId);
my $groupName = shift || $form->get('groupName');
# Get the users we can add
my @manageableUsers = ();
if ($groupName) { # Only adding users from a single group
my $group = WebGUI::Group->find($session, $groupName);
push @manageableUsers, @{ $group->getUsersNotIn($user->friends->getId, 'withoutExpired') };
}
else { # Defaults to groups selected in settings
my $groupIds = $session->setting->get('groupsToManageFriends');
my @groupIds = split "\n", $groupIds;
foreach my $groupId (@groupIds) {
my $group = WebGUI::Group->new($session, $groupId);
next GROUP unless $group->getId || $group->getId eq 'new';
push @manageableUsers, @{ $group->getUsersNotIn($user->friends->getId, 'withoutExpired') };
}
@manageableUsers = uniq @manageableUsers;
}
my $manager = $session->user;
my $i18n = WebGUI::International->new($session);
my @usersToAdd = ();
my $overrideProfile = $session->setting->get('overrideAbleToBeFriend');
USERID: foreach my $newFriendId (@manageableUsers) {
next USERID if $newFriendId eq $userId;
my $user = WebGUI::User->new($session, $newFriendId);
##We don't use acceptsFriendsRequests here because it's overkill.
##No need to check invitations, since friends are managed.
##Existing friends are already filtered out.
next USERID unless $user->get('ableToBeFriend') || $overrideProfile;
push @usersToAdd, [ $newFriendId, $user->username ];
}
tie my %usersToAdd, 'Tie::IxHash';
$usersToAdd{0} = $i18n->get('Select One');
@usersToAdd = sort { $a->[1] cmp $b->[1] } @usersToAdd;
foreach my $newFriend (@usersToAdd) {
$usersToAdd{$newFriend->[0]} = $newFriend->[1];
}
my $var;
$var->{has_friends} = @{$user->friends->getUsers("noexpired")};
$var->{username} = $user->username;
$var->{userId} = $user->userId;
$var->{manageUrl} = $self->getUrl('module=friendManager;do=view');
if ($groupName) {
$var->{groupName} = $groupName;
$var->{viewAllUrl} = $self->getUrl('module=friendManager;do=editFriends;userId='.$userId);
}
my $fb = WebGUI::FormBuilder->new( $session,
name => "friendManager",
action => $self->getUrl('module=friendManager;do=editFriendsSave')
);
$fb->addField( "Hidden", name => "userId", value => $user->userId );
if ( $groupName ) {
$fb->addField( "Hidden", name => 'groupName', value => $groupName );
}
# Add checkboxes to remove friends
my $friendsList = $user->friends->getUserList();
while (my ($userId, $username) = each %{ $friendsList }) {
$fb->addField( "Checkbox", name => 'friendToAxe', value => $userId, label => $username );
}
# Add a selectbox to add friends
$fb->addField( "SelectBox", name => 'userToAdd', options => \%usersToAdd );
$fb->addField( "Checkbox", name => 'removeAllFriends', value => 'all' );
if (!$groupName) {
$fb->addField( "Checkbox", name => 'addManagers', value => 'addManagers' );
}
$fb->addField( 'Submit', name => "send" );
$fb->toTemplateVars( "form_", $var );
return $self->processTemplate($var,$session->setting->get("fmEditTemplateId"));
}
#-------------------------------------------------------------------
=head2 www_editFriendsSave ( )
Handle adding and removing people from a user's friend group. The userId of
the user to modify will be in the userId from variable. One userId to add will be
in userToAdd.
Users to delete will be listed in checkboxes with the name, friendToAxe
=cut
sub www_editFriendsSave () {
my $self = shift;
my $session = $self->session;
my $form = $session->form;
my $userId = $form->process('userId', 'guid');
my $user = WebGUI::User->new($session, $userId);
my $ufriend = WebGUI::Friends->new($session, $user);
my $userToAdd = $form->process('userToAdd', 'guid');
if ($userToAdd) {
$ufriend->add([$userToAdd]);
}
my $addManagers = $form->process('addManagers', 'checkbox');
if ($addManagers eq 'addManagers') {
my $managerGroup = WebGUI::Group->new($session, $session->setting->get('groupIdAdminFriends'));
$ufriend->add($managerGroup->getUsers());
}
##Remove all has priority, that way we don't delete friends twice.
my $removeAll = $form->process('removeAllFriends','checkbox');
my @usersToRemove = $form->process('friendToAxe', 'checkList');
if ($removeAll eq 'all') {
$ufriend->delete($user->friends->getUsers());
}
elsif (scalar @usersToRemove) {
$ufriend->delete(\@usersToRemove);
}
my $groupName = $form->process('groupName');
return $self->www_editFriends($userId, $groupName);
}
#-------------------------------------------------------------------
=head2 www_getFriendsAsJson ( )
For each user in a group, count how many friends they have and return that data
as JSON. Uses the form variable, groupId, to return users for that group.
=cut
sub www_getFriendsAsJson {
my $self = shift;
my $session = $self->session;
return $session->privilege->insufficient
unless $session->user->isInGroup($session->setting->get('groupIdAdminFriends'));
my $form = $session->form;
my $groupId = $form->get('groupId');
if (! $groupId) {;
$session->log->warn("No groupId: >$groupId<");
return '{}';
}
my $group = WebGUI::Group->new($session, $groupId);
return '{}' if $group->getId eq 'new';
if ($group->getId eq 'new') {;
$session->log->warn("New group created");
return '{}';
}
my @records = ();
my $groups = $session->setting->get('groupsToManageFriends');
my @groupIds = split "\n", $groups;
if (scalar @groupIds > 1) {
@groupIds = grep { $_ ne $groupId } @groupIds;
}
my $groupNames = join "\n",
map { $_->name }
map { WebGUI::Group->new($session, $_) }
@groupIds;
USER: foreach my $userId (@{ $group->getUsers} ) {
my $user = WebGUI::User->new($session, $userId);
next USER unless $user;
my $friendsList = $user->friends->getUserList();
my $friendsCount = scalar keys %{ $friendsList };
my $friends = '';
NAME: foreach my $name ( values %{ $friendsList }) {
if (length $friends + length $name < 45) {
if ($friends) {
$friends .= ', ';
}
$friends .= $name;
}
else {
last NAME;
}
}
push @records, {
userId => $userId,
username => $user->username,
friendsCount => $friendsCount,
friends => $friends,
groups => $groupNames,
};
}
##Sort by username to make the datatable happy
@records = map { $_->[1] }
sort { $a->[0] cmp $b->[0] }
map { [ $_->{username}, $_ ] } @records;
my %results;
$results{totalRecords} = scalar @records;
$results{records} = \@records;
$results{'sort'} = 'username';
$self->bare(1);
$session->response->content_type('application/json');
my $json = JSON::to_json(\%results);
return $json;
}
#-------------------------------------------------------------------
=head2 www_view ( )
The main view page for editing the user's friends.
=cut
sub www_view {
my $self = shift;
my $session = $self->session;
my $var = {};
$var->{group_loop} = [];
my $groupIds = $session->setting->get('groupsToManageFriends');
my @groupIds = split "\n", $groupIds;
GROUP: foreach my $groupId (@groupIds) {
my $group = WebGUI::Group->new($session, $groupId);
next GROUP unless $group->getId || $group->getId eq 'new';
push @{ $var->{group_loop} }, {
groupId => $groupId,
groupName => $group->name,
};
}
return $self->processTemplate($var,$session->setting->get("fmViewTemplateId"));
}
1;