RFE for making an user's inbox filterable by the person who sent it.

Includes template changes, i18n, help and tests.
This commit is contained in:
Colin Kuskie 2009-05-13 17:20:40 +00:00
commit 385d35c13b
8 changed files with 196 additions and 70 deletions

View file

@ -23,6 +23,7 @@
- added #9203: Survey Visualization
- Added: United States Postal Service Shipping Driver.
- Refactored transaction tmpl_var generation into WebGUI::Shop::Transaction. ( Martin Kamerbeek / Oqapi )
- rfe #9906: Inbox Filtering
7.7.5
- Adding StoryManager.

View file

@ -223,7 +223,7 @@ sub editSettingsForm {
label => $i18n->get("inbox rich editor label"),
hoverHelp => $i18n->get("inbox rich editor description"),
);
return $f->printRowsOnly;
}
@ -575,7 +575,7 @@ sub www_deleteMessage {
my $message = $inbox->getMessage($messageId);
$self->store->{tab} = "inbox";
if (!(defined $message) || !$inbox->canRead($message)) {
#View will handle displaying these errors
return $self->www_viewMessage;
@ -593,7 +593,7 @@ sub www_deleteMessage {
}
}
$message->delete;
return $self->www_viewMessage($displayMessage->getId);
}
@ -708,7 +708,7 @@ sub www_inviteUser {
my $form = $session->form;
my $setting = $session->setting;
my $user = $session->user;
my $displayError = shift;
my $var = {};
@ -717,11 +717,11 @@ sub www_inviteUser {
#Add any error passed in to be displayed if the form reloads
$var->{'message_display_error'} = $displayError;
#Message From
$var->{'message_from' } = $user->getWholeName;
$var->{'message_from_id' } = $user->userId;
#Message To
$var->{'form_to' } = WebGUI::Form::email($session, {
name => "to",
@ -772,7 +772,7 @@ sub www_inviteUser {
action => $self->getUrl("module=inbox;do=inviteUserSave"),
extras => q{name="inviteForm"}
});
$var->{'submit_button' } = WebGUI::Form::submit($session,{});
$var->{'form_footer' } = WebGUI::Form::formFooter($session, {});
$var->{'back_url' } = $session->env->get("HTTP_REFERER") || $var->{'view_inbox_url'};
@ -803,7 +803,7 @@ sub www_inviteUserSave {
#Must have a person to send email to
my $to = $form->get('to');
return $self->www_inviteUser($i18n->get('missing email')) unless $to;
#Must have a subject
my $defaultSubject = $setting->get("inboxInviteUserSubject");
WebGUI::Macro::process($session,\$defaultSubject);
@ -887,11 +887,11 @@ sub www_manageInvitations {
my $i18n = WebGUI::International->new($session,'Account_Inbox');
$self->store->{tab} = "invitations";
#Deal with rows per page
my $rpp = $session->form->get("rpp") || 25;
my $rpp_url = ";rpp=$rpp";
#Cache the base url
my $inboxUrl = $self->getUrl("op=account;module=inbox;do=manageInvitations");
@ -903,15 +903,15 @@ sub www_manageInvitations {
$rpp
);
$p->setDataByQuery($sql,undef,undef,[$user->userId]);
#Export page to template
my @msg = ();
foreach my $row ( @{$p->getPageData} ) {
my $inviter = WebGUI::User->new($session,$row->{inviterId});
next if($inviter->isVisitor); # Inviter account got deleted
my $epoch = WebGUI::DateTime->new(mysql => $row->{dateSent} )->epoch;
my $hash = {};
$hash->{'invite_id' } = $row->{inviteId};
$hash->{'message_url' } = $self->getUrl("module=inbox;do=viewInvitation;inviteId=".$row->{inviteId});
@ -927,7 +927,7 @@ sub www_manageInvitations {
push(@msg,$hash);
}
my $msgCount = $p->getRowCount;
$var->{'message_loop' } = \@msg;
$var->{'has_messages' } = $msgCount > 0;
$var->{'message_total' } = $msgCount;
@ -989,7 +989,7 @@ sub www_sendMessage {
#Add common template variable for displaying the inbox
my $inbox = WebGUI::Inbox->new($session);
$self->appendCommonVars($var,$inbox);
my $messageId = $form->get("messageId");
my $userId = $form->get("userId");
my $pageUrl = $session->url->page;
@ -999,7 +999,7 @@ sub www_sendMessage {
if($messageId) {
#This is a reply to a message - automate who the user is
my $message = $inbox->getMessage($messageId);
#Handle Errors
if (!(defined $message)) {
#Message doesn't exist
@ -1046,14 +1046,14 @@ sub www_sendMessage {
$var->{'isInbox'} = "true";
return $self->showError($var,$errorMsg,$backUrl,$self->getInboxErrorTemplateId);
}
$var->{'isPrivateMessage'} = "true";
$var->{'message_to' } = $toUser->getWholeName;
}
else {
#This is a new message
$var->{'isNew' } = "true";
my $friends = $fromUser->friends->getUserList;
my @checkedFriends = ();
my @friendsChecked = $form->process("friend","checkList");
@ -1091,7 +1091,7 @@ sub www_sendMessage {
push (@friendsLoop, $friendHash);
}
#You can't send new messages if you don't have any friends to send to
unless($activeFriendCount) {
my $i18n = WebGUI::International->new($session,'Account_Inbox');
@ -1103,9 +1103,9 @@ sub www_sendMessage {
$var->{'friends_loop' } = \@friendsLoop;
$var->{'checked_fiends_loop'} = \@checkedFriends;
}
$var->{'message_from' } = $fromUser->getWholeName;
my $subject = $form->get("subject");
if($subject eq "" && $messageId) {
$subject = "Re: ".$var->{'message_subject'};
@ -1118,7 +1118,7 @@ sub www_sendMessage {
});
$var->{'message_body' } = $form->get('message');
$var->{'form_message_text'} = WebGUI::Form::textarea($session, {
name =>"message",
value =>$var->{'message_body'} || "",
@ -1132,12 +1132,12 @@ sub www_sendMessage {
width => "600",
richEditId => $self->getRichEditorId,
});
$var->{'form_header' } = WebGUI::Form::formHeader($session,{
action => $self->getUrl("module=inbox;do=sendMessageSave;messageId=$messageId;userId=$userId"),
extras => q{name="messageForm"}
});
$var->{'submit_button' } = WebGUI::Form::submit($session,{});
$var->{'form_footer' } = WebGUI::Form::formFooter($session, {});
$var->{'back_url' } = $backUrl;
@ -1166,7 +1166,7 @@ sub www_sendMessageSave {
#Add common template variable for displaying the inbox
my $inbox = WebGUI::Inbox->new($session);
my $messageId = $form->get("messageId");
my $userId = $form->get("userId");
my @friends = $form->get("friend","checkList");
@ -1255,11 +1255,11 @@ sub www_view {
my $var = {};
$self->store->{tab} = "inbox";
#Deal with sort order
my $sortBy = $session->form->get("sortBy") || undef;
my $sort_url = ($sortBy)?";sortBy=$sortBy":"";
#Deal with sort direction
my $sortDir = $session->form->get("sortDir") || "desc";
my $sortDir_url = ";sortDir=".(($sortDir eq "desc")?"asc":"desc");
@ -1267,26 +1267,37 @@ sub www_view {
#Deal with rows per page
my $rpp = $session->form->get("rpp") || 25;
my $rpp_url = ";rpp=$rpp";
#Deal with user filtering
my $userFilter = $session->form->get("userFilter") || 'all';
my $userFilter_url = ";userFilter=$userFilter";
#Cache the base url
my $inboxUrl = $self->getUrl;
my $urlFrag = $sortDir_url . $rpp_url . $userFilter_url;
#Create sortBy headers
$var->{'subject_url' } = $inboxUrl.";sortBy=subject".$sortDir_url.$rpp_url;
$var->{'status_url' } = $inboxUrl.";sortBy=status".$sortDir_url.$rpp_url;
$var->{'from_url' } = $inboxUrl.";sortBy=sentBy".$sortDir_url.$rpp_url;
$var->{'dateStamp_url' } = $inboxUrl.";sortBy=dateStamp".$sortDir_url.$rpp_url;
$var->{'rpp_url' } = $inboxUrl.$sort_url.";sortDir=".$sortDir;
$var->{'subject_url' } = $inboxUrl.";sortBy=subject" . $urlFrag;
$var->{'status_url' } = $inboxUrl.";sortBy=status" . $urlFrag;
$var->{'from_url' } = $inboxUrl.";sortBy=sentBy" . $urlFrag;
$var->{'dateStamp_url' } = $inboxUrl.";sortBy=dateStamp" . $urlFrag;
$var->{'rpp_url' } = $inboxUrl.$sort_url.$sortDir_url.$userFilter_url;
#Create the paginator
my $inbox = WebGUI::Inbox->new($session);
my $p = $inbox->getMessagesPaginator($session->user,{
my $messageOptions = {
sortBy => $sortBy,
sortDir => $sortDir,
baseUrl => $inboxUrl.$sort_url.";sortDir=".$sortDir.$rpp_url,
paginateAfter => $rpp
});
baseUrl => $inboxUrl.$sort_url.$sortDir_url.$rpp_url.$userFilter_url,
paginateAfter => $rpp,
};
if ($userFilter ne 'all') {
$messageOptions->{whereClause} = sprintf 'ibox.sentBy=%s', $session->db->quote($session->form->get('userFilter'));
}
my $p = $inbox->getMessagesPaginator($session->user, $messageOptions);
#Export page to template
my @msg = ();
foreach my $row ( @{$p->getPageData} ) {
@ -1315,7 +1326,7 @@ sub www_view {
push(@msg,$hash);
}
my $msgCount = $p->getRowCount;
$var->{'message_loop' } = \@msg;
$var->{'has_messages' } = $msgCount > 0;
$var->{'message_total' } = $msgCount;
@ -1331,6 +1342,20 @@ sub www_view {
extras => q{onchange="location.href='}.$var->{'rpp_url'}.q{;rpp='+this.options[this.selectedIndex].value"}
});
my $userSql = $inbox->getMessageSql(undef, { 'select' => <<EOSQL, });
ibox.sentBy,
(IF(userProfileData.firstName != '' and userProfileData.firstName is not null and userProfileData.lastName !='' and userProfileData.lastName is not null, concat(userProfileData.firstName,' ',userProfileData.lastName),users.username)) as fullName
EOSQL
tie my %userHash, 'Tie::IxHash';
my $i18n = WebGUI::International->new($session, 'Account_Inbox');
%userHash = ( 'all' => $i18n->get('All users'), $session->db->buildHash($userSql) );
$var->{'userFilter'} = WebGUI::Form::selectBox($session,{
name => 'userFilter',
options => \%userHash,
value => $session->form->get('userFilter') || 'all',
extras => q{onchange="location.href='}.$inboxUrl.q{;userFilter='+this.options[this.selectedIndex].value"}
});
$var->{'form_header'} = WebGUI::Form::formHeader($session,{
action => $self->getUrl("module=inbox;do=actOnMessages")
});
@ -1386,9 +1411,9 @@ sub www_viewInvitation {
$var->{'isInvitation'} = "true";
return $self->showError($var,$errorMsg,$backUrl,$self->getInboxErrorTemplateId);
}
my $epoch = WebGUI::DateTime->new(mysql => $invitation->{dateSent} )->epoch;
$var->{'invite_id' } = $inviteId;
$var->{'message_from_id' } = $inviter->userId;
$var->{'message_from' } = $inviter->getWholeName;
@ -1405,7 +1430,7 @@ sub www_viewInvitation {
|| $var->{'message_body'} =~ /\<p/ig) {
$var->{'message_body'} =~ s/\n/\<br \/\>\n/g;
}
#Build the action URLs
my $nextInvitation = $friends->getPreviousInvitation($invitation); #Messages sorted descending so next is actually previous
if( $nextInvitation->{inviteId} ) {
@ -1461,7 +1486,7 @@ sub www_viewMessage {
#Add common template variable for displaying the inbox
$self->appendCommonVars($var,$inbox);
#Handler Errors
if (!(defined $message)) {
my $i18n = WebGUI::International->new($session,'Account_Inbox');
@ -1477,7 +1502,7 @@ sub www_viewMessage {
$var->{'isInvitation'} = "true";
return $self->showError($var,$errorMsg,$backUrl,$self->getInboxErrorTemplateId);
}
$message->setStatus("read") unless ($message->isRead);
$var->{'message_id' } = $messageId;

View file

@ -23,6 +23,7 @@ our $HELP = {
{ name => 'invitations_enabled', },
{ name => 'user_invitations_enabled', },
{ name => 'invite_friend_url', },
{ name => 'userFilter', },
],
related => [ ],
},

View file

@ -154,7 +154,8 @@ sub getMessage {
=head2 getNextMessage ( message [, userId] )
Returns the message that was send after the message passed in for the user
Returns the message that was sent after the message passed in for the user. This is always assumed
to be in date order.
=head3 message
@ -188,11 +189,12 @@ sub getNextMessage {
=head2 getPreviousMessage ( message [, userId] )
Returns the message that was sent before the message passed in for the user
Returns the message that was sent before the message passed in for the user. This is always assumed
to be sorted in date order.
=head3 message
The message to find the previous message for
The message to find the previous message for.
=head3 user
@ -240,6 +242,10 @@ An integer indication the page to return. Defaults to 1
The column to sort by
=head3 where
An extra clause for filtering results.
=cut
sub getMessagesForUser {
@ -248,13 +254,14 @@ sub getMessagesForUser {
my $perpage = shift || 50;
my $page = shift || 1;
my $sortBy = shift;
my $where = shift;
my $p = $self->getMessagesPaginator( $user , {
sortBy => $sortBy,
sortDir => "desc",
paginateAfter => $perpage,
pageNumber => $page
pageNumber => $page,
whereClause => $where,
});
return $self->getMessagesOnPage($p);
@ -332,6 +339,10 @@ Specify the form variable the paginator should use in its links. Defaults to "p
By default the page number will be determined by looking at $self->session->form->process("pn"). If that is empty the page number will be defaulted to "1". If you'd like to override the page number specify it here.
=head4 whereClause
An extra clause to filter the results returned by the paginator.
=cut
sub getMessagesPaginator {
@ -347,6 +358,7 @@ sub getMessagesPaginator {
my $paginateAfter = $properties->{paginateAfter};
my $formVar = $properties->{formVar};
my $pageNumber = $properties->{pageNumber};
my $whereClause = $properties->{whereClause} || '';
#Make sure a valid sortBy is passed in
if($sortBy && !WebGUI::Utility::isIn($sortBy,qw( subject sentBy dateStamp status ))) {
@ -368,13 +380,12 @@ sub getMessagesPaginator {
}
my $sql = $self->getMessageSql($user, {
user => $user,
sortBy => $sortBy,
sortDir => $sortDir
user => $user,
sortBy => $sortBy,
sortDir => $sortDir,
whereClause => $whereClause,
});
#$session->log->warn($sql);
my $p = WebGUI::Paginator->new(
$session,
$baseUrl,
@ -439,6 +450,7 @@ sub getMessageSql {
my $sortDir = $props->{sortDir};
my $whereClause = $props->{whereClause};
my $limit = $props->{limit};
my $select = $props->{'select'};
if($sortBy) {
$sortBy = qq{ORDER BY $sortBy $sortDir};
@ -452,6 +464,14 @@ sub getMessageSql {
$limit = qq{LIMIT $limit};
}
if(!$select) {
$select =<<SELECT;
ibox.messageId, ibox.subject, ibox.sentBy, ibox.dateStamp,
(IF(ibox.status = 'completed' or ibox.status = 'pending',ibox.status,IF(inbox_messageState.repliedTo,'replied',IF(inbox_messageState.isRead,'read','unread')))) as messageStatus,
(IF(userProfileData.firstName != '' and userProfileData.firstName is not null and userProfileData.lastName !='' and userProfileData.lastName is not null, concat(userProfileData.firstName,' ',userProfileData.lastName),users.username)) as fullName
SELECT
}
my $messageLimit = 20_000;
my $limitHalf = $messageLimit / 2;
my $limitQuarter = $messageLimit / 4;
@ -461,9 +481,7 @@ sub getMessageSql {
# for performance purposes don't use datasets larger than 20000 no matter how man messages are in the inbox
my $sql = qq{
SELECT
ibox.messageId, ibox.subject, ibox.sentBy, ibox.dateStamp,
(IF(ibox.status = 'completed' or ibox.status = 'pending',ibox.status,IF(inbox_messageState.repliedTo,'replied',IF(inbox_messageState.isRead,'read','unread')))) as messageStatus,
(IF(userProfileData.firstName != '' and userProfileData.firstName is not null and userProfileData.lastName !='' and userProfileData.lastName is not null, concat(userProfileData.firstName,' ',userProfileData.lastName),users.username)) as fullName
$select
FROM (
( SELECT messageId, subject, sentBy, dateStamp, status FROM inbox WHERE userId = '$userId' order by dateStamp desc limit $limitHalf)
UNION

View file

@ -97,12 +97,22 @@ Email message to use rather than inbox message contents.
Email subject to use rather than inbox message subject.
=head3 options
A hash reference containing options for handling the message.
=head4 testing
If testing is true, then no email will be made or sent. Only
the inbox message will be made.
=cut
sub create {
my $class = shift;
my $session = shift;
my $properties = shift;
my $class = shift;
my $session = shift;
my $properties = shift;
my $options = shift || {};
my $self = {};
$self->{_properties}{messageId} = "new";
$self->{_properties}{status} = $properties->{status} || "pending";
@ -149,11 +159,13 @@ sub create {
}
my $subject = (defined $properties->{emailSubject}) ? $properties->{emailSubject} : $self->{_properties}{subject};
my $mail = WebGUI::Mail::Send->create($session, {
toUser=>$self->{_properties}{userId},
toGroup=>$self->{_properties}{groupId},
subject=>$subject,
});
my $mail = $options->{testing}
? undef
: WebGUI::Mail::Send->create($session, {
toUser=>$self->{_properties}{userId},
toGroup=>$self->{_properties}{groupId},
subject=>$subject,
});
if (defined $mail) {
my $preface = "";
my $fromUser = WebGUI::User->new($session, $properties->{sentBy});

View file

@ -726,6 +726,18 @@ our $I18N = {
context => "template variable for view inbox template",
},
'userFilter' => {
message => q{A select box form element to filter the list of messages by who sent them.},
lastUpdated => 1235421123,
context => "Description of Inbox setting",
},
'All users' => {
message => q{All users},
lastUpdated => 1235421123,
context => "Default setting for filtering in the Inbox. Short for Show messages from all users.",
},
};
1;

View file

@ -17,12 +17,12 @@ use WebGUI::Session;
use WebGUI::Inbox;
use WebGUI::User;
use Test::More tests => 8; # increment this value for each test you create
use Test::More tests => 13; # increment this value for each test you create
my $session = WebGUI::Test->session;
# get a user so we can test retrieving messages for a specific user
my $user = WebGUI::User->new($session, 3);
my $admin = WebGUI::User->new($session, 3);
# Begin tests by getting an inbox object
my $inbox = WebGUI::Inbox->new($session);
@ -57,10 +57,67 @@ ok($message->getId == $messageId, 'getMessage returns message object');
#########################################################
# get a list (arrayref) of messages for a specific user #
#########################################################
my $messageList = $inbox->getMessagesForUser($user);
my $messageList = $inbox->getMessagesForUser($admin);
my $message_cnt = scalar(@{$messageList});
ok($message_cnt > 0, 'Messages returned for user');
is($message_cnt, 1, 'User only has 1 messages');
$message->setDeleted(3);
is(scalar(@{ $inbox->getMessagesForUser($admin) }), 0, 'User has no undeleted messages');
$message->delete(3);
#########################################################
#
# Check user filtering
#
#########################################################
my @senders = ();
push @senders, WebGUI::User->create($session);
push @senders, WebGUI::User->create($session);
push @senders, WebGUI::User->create($session);
#WebGUI::Test->usersToDelete(@senders);
$senders[0]->username('first');
$senders[0]->profileField('firstName', 'First Only');
$senders[1]->username('last');
$senders[1]->profileField('lastName', 'Last Only');
$senders[2]->username('wholename');
$senders[2]->profileField('firstName', 'Tom');
$senders[2]->profileField('lastName', 'Jones');
$inbox->addMessage({
message => "First message",
userId => 3,
sentBy => $senders[0]->userId,
});
$inbox->addMessage({
message => "Second message",
userId => 3,
sentBy => $senders[1]->userId,
});
$inbox->addMessage({
message => "Third message",
userId => 3,
sentBy => $senders[2]->userId,
});
$inbox->addMessage({
message => "Fourth message",
userId => 3,
sentBy => $senders[2]->userId,
});
is(scalar @{ $inbox->getMessagesForUser($admin) }, 4, 'Added 3 messages by various users');
is(scalar @{ $inbox->getMessagesForUser($admin, '', '', '', 'sentBy='.$session->db->quote($senders[0]->userId)) }, 1, '1 message by sender[0]');
is(scalar @{ $inbox->getMessagesForUser($admin, '', '', '', 'sentBy='.$session->db->quote($senders[1]->userId)) }, 1, '1 message by sender[1]');
is(scalar @{ $inbox->getMessagesForUser($admin, '', '', '', 'sentBy='.$session->db->quote($senders[2]->userId)) }, 2, '2 messages by sender[2]');
END {
$session->db->write('delete from inbox where messageId = ?', [$message->getId]);
# foreach my $message (@{ $inbox->getMessagesForUser($admin, 1000) } ) {
# $message->setDeleted(3);
# $message->delete(3);
# }
}