diff --git a/docs/changelog/7.x.x.txt b/docs/changelog/7.x.x.txt index 760bf1d67..2ad2ef161 100644 --- a/docs/changelog/7.x.x.txt +++ b/docs/changelog/7.x.x.txt @@ -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. diff --git a/docs/upgrades/packages-7.7.6/root_import_account_inbox_default-inbox-view-template.wgpkg b/docs/upgrades/packages-7.7.6/root_import_account_inbox_default-inbox-view-template.wgpkg index a3d92c1c7..d9c988e4f 100644 Binary files a/docs/upgrades/packages-7.7.6/root_import_account_inbox_default-inbox-view-template.wgpkg and b/docs/upgrades/packages-7.7.6/root_import_account_inbox_default-inbox-view-template.wgpkg differ diff --git a/lib/WebGUI/Account/Inbox.pm b/lib/WebGUI/Account/Inbox.pm index 49ca9128a..bc186a78c 100644 --- a/lib/WebGUI/Account/Inbox.pm +++ b/lib/WebGUI/Account/Inbox.pm @@ -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' => <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'} =~ /\

{'message_body'} =~ s/\n/\
\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; diff --git a/lib/WebGUI/Help/Account_Inbox.pm b/lib/WebGUI/Help/Account_Inbox.pm index cc1eec31d..8e4640f2f 100644 --- a/lib/WebGUI/Help/Account_Inbox.pm +++ b/lib/WebGUI/Help/Account_Inbox.pm @@ -23,6 +23,7 @@ our $HELP = { { name => 'invitations_enabled', }, { name => 'user_invitations_enabled', }, { name => 'invite_friend_url', }, + { name => 'userFilter', }, ], related => [ ], }, diff --git a/lib/WebGUI/Inbox.pm b/lib/WebGUI/Inbox.pm index 5841efd4a..cee28c382 100644 --- a/lib/WebGUI/Inbox.pm +++ b/lib/WebGUI/Inbox.pm @@ -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 =<{_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}); diff --git a/lib/WebGUI/i18n/English/Account_Inbox.pm b/lib/WebGUI/i18n/English/Account_Inbox.pm index 28a089fec..6fcf597ff 100644 --- a/lib/WebGUI/i18n/English/Account_Inbox.pm +++ b/lib/WebGUI/i18n/English/Account_Inbox.pm @@ -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; diff --git a/t/Inbox.t b/t/Inbox.t index 87dfb6e28..17682fe41 100644 --- a/t/Inbox.t +++ b/t/Inbox.t @@ -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); +# } }