diff --git a/lib/WebGUI/Account/FriendManager.pm b/lib/WebGUI/Account/FriendManager.pm new file mode 100644 index 000000000..44bcf36e9 --- /dev/null +++ b/lib/WebGUI/Account/FriendManager.pm @@ -0,0 +1,375 @@ +package WebGUI::Account::FriendManager; + +use strict; + +use WebGUI::Exception; +use WebGUI::Friends; +use WebGUI::International; +use WebGUI::Pluggable; +use WebGUI::Utility; +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 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::HTMLForm->new($session); + + $f->group( + name => "groupIdAdminFriends", + value => $session->setting->get('groupIdAdminFriends'), + label => $i18n->get("setting groupIdAdminFriends label"), + hoverHelp => $i18n->get("setting groupIdAdminFriends hoverHelp"), + ); + $f->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->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->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->yesNo( + name => "overrideAbleToBeFriend", + value => $self->session->setting->get("overrideAbleToBeFriend"), + label => $i18n->get("override abletobefriend label"), + hoverHelp => $i18n->get("override abletobefriend hoverHelp"), + ); + + return $f->printRowsOnly; +} + +#------------------------------------------------------------------- + +=head2 editSettingsFormSave ( ) + +Save + +=cut + +sub editSettingsFormSave { + my $self = shift; + my $session = $self->session; + my $setting = $session->setting; + my $form = $session->form; + + $setting->set("fmViewTemplateId", $form->process("fmViewTemplateId", "template")); + $setting->set("fmEditTemplateId", $form->process("fmEditTemplateId", "template")); + my $groupsToManageFriends = $form->process("groupsToManageFriends", "group"); + $setting->set("groupsToManageFriends", $groupsToManageFriends); + $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'); + + ##List users in my friends group. Each friend gets a delete link. + my $friendsList = $user->friends->getUserList(); + my @friends_loop = (); + while (my ($userId, $username) = each %{ $friendsList }) { + push @friends_loop, { + userId => $userId, + username => $username, + checkForm => WebGUI::Form::checkbox($session, { + name => 'friendToAxe', + value => $userId, + }), + }; + } + + ##List users in all administrated groups. Friends are added one at a time. + my @manageableUsers = (); + if ($groupName) { + my $group = WebGUI::Group->find($session, $groupName); + push @manageableUsers, @{ $group->getUsersNotIn($user->{_user}->{'friendsGroup'}, 'withoutExpired') }; + } + else { + 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->{_user}->{'friendsGroup'}, 'withoutExpired') }; + } + @manageableUsers = uniq @manageableUsers; + } + my %usersToAdd = (); + tie %usersToAdd, 'Tie::IxHash'; + my $manager = $session->user; + my $i18n = WebGUI::International->new($session); + $usersToAdd{0} = $i18n->get('Select One'); + 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->profileField('ableToBeFriend') || $overrideProfile; + push @usersToAdd, [ $newFriendId, $user->username ]; + } + + @usersToAdd = sort { $a->[1] cmp $b->[1] } @usersToAdd; + foreach my $newFriend (@usersToAdd) { + $usersToAdd{$newFriend->[0]} = $newFriend->[1]; + } + + my $var; + $var->{formHeader} = WebGUI::Form::formHeader($session, { + action => $self->getUrl('module=friendManager;do=editFriendsSave'), + }) + . WebGUI::Form::hidden($session, { name => 'userId', value => $user->userId } ); + if ($groupName) { + $var->{formHeader} .= WebGUI::Form::hidden($session, { name => 'groupName', value => $groupName }); + } + $var->{addUserForm} = WebGUI::Form::selectBox($session, { + name => 'userToAdd', + options => \%usersToAdd, + }); + $var->{friends_loop} = \@friends_loop; + $var->{has_friends} = scalar @friends_loop; + $var->{submit} = WebGUI::Form::submit($session); + $var->{formFooter} = WebGUI::Form::formFooter($session); + $var->{username} = $user->username; + $var->{userId} = $user->userId; + $var->{manageUrl} = $self->getUrl('module=friendManager;do=view'); + $var->{removeAll} = WebGUI::Form::checkbox($session, { name => 'removeAllFriends', value => 'all', }); + if (! $groupName) { + $var->{addManagers} = WebGUI::Form::checkbox($session, { name => 'addManagers', value => 'addManagers', }); + } + if ($groupName) { + $var->{groupName} = $groupName; + $var->{viewAllUrl} = $self->getUrl('module=friendManager;do=editFriends;userId='.$userId); + } + 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->http->setMimeType('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; diff --git a/lib/WebGUI/Help/Account_FriendManager.pm b/lib/WebGUI/Help/Account_FriendManager.pm new file mode 100644 index 000000000..06bf30e89 --- /dev/null +++ b/lib/WebGUI/Help/Account_FriendManager.pm @@ -0,0 +1,60 @@ +package WebGUI::Help::Account_FriendManager; + +use strict; + +our $HELP = { + + 'view friend manager' => { + title => 'Friend Manager View Template', + body => '', + isa => [ + ], + fields => [ ], + variables => [ + { name => 'group_loop', + variables => [ + { name => 'groupId', }, + { name => 'groupName', }, + ] + }, + ], + related => [ ], + }, + + 'edit friend manager' => { + title => 'Friend Manager Edit Template', + body => '', + isa => [ + ], + fields => [ ], + variables => [ + { name => 'formHeader', + required => 1, }, + { name => 'username', }, + { name => 'userId', }, + { name => 'manageUrl', }, + { name => 'addUserForm', }, + { name => 'hasFriends', }, + { name => 'friend_loop', + variables=> [ + { name => 'userId', + description => 'new userId', }, + { name => 'username', + description => 'new username', }, + { name => 'checkForm', }, + ], + }, + { name => 'removeAll', }, + { name => 'addManagers', }, + { name => 'submit', + required => 1, }, + { name => 'formFooter', + required => 1, }, + ], + related => [ ], + }, + +}; + +1; +#vim:ft=perl diff --git a/lib/WebGUI/i18n/English/Account_FriendManager.pm b/lib/WebGUI/i18n/English/Account_FriendManager.pm new file mode 100644 index 000000000..4fbc13e42 --- /dev/null +++ b/lib/WebGUI/i18n/English/Account_FriendManager.pm @@ -0,0 +1,195 @@ +package WebGUI::i18n::English::Account_FriendManager; +use strict; + +our $I18N = { + + 'setting groupIdAdminFriends label' => { + message => q{Friends Manager}, + lastUpdated => 0, + }, + + 'setting groupIdAdminFriends hoverHelp' => { + message => q{Group to manage friends, to assign people to one another and to view the interface for managing friends.}, + lastUpdated => 0, + }, + + 'view template label' => { + message => q{View Template}, + lastUpdated => 0, + }, + + 'view template hoverHelp' => { + message => q{This template renders the Friend Manager itself, inside the layout and style templates.}, + lastUpdated => 0, + }, + + 'edit template label' => { + message => q{Edit Friends Template}, + lastUpdated => 0, + }, + + 'edit template hoverHelp' => { + message => q{This template renders the interface for adding or removing friends for a user.}, + lastUpdated => 0, + }, + + 'groupsToManageFriends label' => { + message => q{Groups to Manage as Friends}, + lastUpdated => 0, + }, + + 'groupsToManageFriends hoverHelp' => { + message => q{Choose groups of users whose Friends Networks you want to Manage.}, + lastUpdated => 0, + }, + + 'override abletobefriend label' => { + message => q{Override ableToBeFriend profile setting?}, + lastUpdated => 0, + }, + + 'override abletobefriend hoverHelp' => { + message => q{If a user has set their ableToBeFriend profile option to 'No', then the Friend Manager will not display them as a friend to be added. If this option is set to Yes, then the Friend Manager will allow managing them.}, + lastUpdated => 0, + }, + + 'title' => { + message => q{Friend Manager}, + lastUpdated => 0, + }, + + 'remove friends' => { + message => q{Remove Friends}, + lastUpdated => 0, + }, + + 'add new friends' => { + message => q{Add New Friends}, + lastUpdated => 0, + }, + + 'Friend Manager View Template' => { + message => q{Friend Manager View Template}, + lastUpdated => 0, + }, + + 'group_loop' => { + message => q{A loop containing 1 entry for each group that is set to be managed.}, + lastUpdated => 0, + }, + + 'groupId' => { + message => q{The GUID of the group.}, + lastUpdated => 0, + }, + + 'groupName' => { + message => q{The name of the group.}, + lastUpdated => 0, + }, + + 'Friend Manager Edit Template' => { + message => q{Friend Manager Edit Template}, + lastUpdated => 0, + }, + + 'formHeader' => { + message => q{HTML code to begin the form for editing a user's list of friends.}, + lastUpdated => 0, + }, + + 'username' => { + message => q{The name of the user whose friends you are managing.}, + lastUpdated => 0, + }, + + 'userId' => { + message => q{The GUID of the user whose friends you are managing.}, + lastUpdated => 0, + }, + + 'manageUrl' => { + message => q{The GUID of the user whose friends you are managing.}, + lastUpdated => 0, + }, + + 'back to friend manager' => { + message => q{Back to the Friend Manager.}, + lastUpdated => 0, + }, + + 'addUserForm' => { + message => q{A dropdown box with a list of users who can be added to this user's Friends.}, + lastUpdated => 0, + }, + + 'hasFriends' => { + message => q{A boolean which is true if the user currently has friends.}, + lastUpdated => 0, + }, + + 'friend_loop' => { + message => q{A loop containing a list of the this user's current friends.}, + lastUpdated => 0, + }, + + 'new userId' => { + message => q{The GUID of a user.}, + lastUpdated => 0, + }, + + 'new username' => { + message => q{The username of a user.}, + lastUpdated => 0, + }, + + 'checkForm' => { + message => q{A checkbox for this user. If set when the form is submitted, this user will be removed from the user's list of friends.}, + lastUpdated => 0, + }, + + 'removeAll' => { + message => q{A checkbox to remove all friends from this user.}, + lastUpdated => 0, + }, + + 'remove all' => { + message => q{Remove all}, + context => q{Template label. To remove all members of a set, to emtpy it.}, + lastUpdated => 0, + }, + + 'addManagers' => { + message => q{A checkbox to add all users in the Friend Manager group to this users's list of Friends.}, + lastUpdated => 0, + }, + + 'Add Friend Managers' => { + message => q{Add Friend Managers}, + context => q{Template label. To add all Friend Managers to this list of friends.}, + lastUpdated => 0, + }, + + 'submit' => { + message => q{A button with internationalized label to submit the form.}, + lastUpdated => 0, + }, + + 'formFooter' => { + message => q{HTML code to end the form.}, + lastUpdated => 0, + }, + + 'view users from all groups' => { + message => q{View users from all groups.}, + lastUpdated => 0, + }, + + 'friends count' => { + message => q{Friends Count}, + lastUpdated => 0, + }, + +}; + +1;