this change will fix the problems with the userProfileData table being way too big. it also simplifies many basic user search tasks, not needing to join the userProfileData table
567 lines
13 KiB
Perl
567 lines
13 KiB
Perl
package WebGUI::Inbox;
|
|
|
|
=head1 LEGAL
|
|
|
|
-------------------------------------------------------------------
|
|
WebGUI is Copyright 2001-2009 Plain Black Corporation.
|
|
-------------------------------------------------------------------
|
|
Please read the legal notices (docs/legal.txt) and the license
|
|
(docs/license.txt) that came with this distribution before using
|
|
this software.
|
|
-------------------------------------------------------------------
|
|
http://www.plainblack.com info@plainblack.com
|
|
-------------------------------------------------------------------
|
|
|
|
=cut
|
|
|
|
use strict;
|
|
use WebGUI::Inbox::Message;
|
|
|
|
=head1 NAME
|
|
|
|
Package WebGUI::Inbox;
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
This class provides a message routing system, which is primarily used by WebGUI's workflow engine.
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
use WebGUI::Inbox;
|
|
|
|
=head1 METHODS
|
|
|
|
These methods are available from this class:
|
|
|
|
=cut
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 addMessage ( properties )
|
|
|
|
Adds a new message to the inbox.
|
|
|
|
=head3 properties
|
|
|
|
See WebGUI::Inbox::Message::create() for details.
|
|
|
|
=cut
|
|
|
|
sub addMessage {
|
|
my $self = shift;
|
|
return WebGUI::Inbox::Message->create($self->session, @_);
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 addPrivateMessage ( properties[, userToSend] )
|
|
|
|
Adds a new private message to the inbox if the user accepts private messages.
|
|
|
|
=head3 properties
|
|
|
|
See WebGUI::Inbox::Message::addMessage() for details.
|
|
|
|
=cut
|
|
|
|
sub addPrivateMessage {
|
|
my $self = shift;
|
|
my $messageData = shift;
|
|
my $isReply = shift;
|
|
|
|
my $userId = $messageData->{userId};
|
|
my $sentBy = $messageData->{sentBy} || $self->session->user->userId;
|
|
return undef unless $userId;
|
|
|
|
my $u = WebGUI::User->new($self->session,$userId);
|
|
return undef unless ($isReply || $u->acceptsPrivateMessages($sentBy));
|
|
|
|
return $self->addMessage($messageData);
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 canRead ( messageId [, user] )
|
|
|
|
Returns whether or not a user can view the message passed in.
|
|
|
|
=head3 message
|
|
|
|
A WebGUI::Inbox::Message object
|
|
|
|
=head3 user
|
|
|
|
WebGUI::User object to test against. Defaults to the current user.
|
|
|
|
=cut
|
|
|
|
sub canRead {
|
|
my $self = shift;
|
|
my $session = $self->session;
|
|
my $message = shift;
|
|
my $user = shift || $session->user;
|
|
|
|
unless (ref $message eq "WebGUI::Inbox::Message") {
|
|
$session->log->warn("Message passed in was either empty or not a valid WebGUI::Inbox::Message. Got: ".(ref $message));
|
|
return 0
|
|
}
|
|
|
|
my $userId = $message->get("userId");
|
|
my $groupId = $message->get("groupId");
|
|
|
|
return ($user->userId eq $userId
|
|
|| (defined $groupId && $user->isInGroup($groupId))
|
|
|| ($user->isInGroup($session->setting->get('groupIdAdminUser')))
|
|
);
|
|
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 deleteMessagesForUser ( $user )
|
|
|
|
Deletes all messages for a user.
|
|
|
|
=head3 $user
|
|
|
|
A WebGUI::User object, representing the user who will have all their messages deleted.
|
|
|
|
=cut
|
|
|
|
sub deleteMessagesForUser {
|
|
my $self = shift;
|
|
my $user = shift;
|
|
|
|
my $messages = $self->getMessagesForUser($user, 1e10);
|
|
my $userId = $user->userId;
|
|
foreach my $message (@{ $messages }) {
|
|
$message->delete($userId);
|
|
}
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getMessage ( messageId [, userId] )
|
|
|
|
Returns a WebGUI::Inbox::Message object.
|
|
|
|
=head3 messageId
|
|
|
|
The id of the message to retrieve.
|
|
|
|
=head3 userId
|
|
|
|
The id of the user to retrieve the message for. Defaults to the current user.
|
|
|
|
=cut
|
|
|
|
sub getMessage {
|
|
my $self = shift;
|
|
my $messageId = shift;
|
|
my $userId = shift;
|
|
|
|
return WebGUI::Inbox::Message->new($self->session, $messageId, $userId);
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getNextMessage ( message [, userId] )
|
|
|
|
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
|
|
|
|
The message to find the next message for
|
|
|
|
=head3 user
|
|
|
|
The WebGUI::User object of the user to retrieve the message for. Defaults to the current user.
|
|
|
|
=cut
|
|
|
|
sub getNextMessage {
|
|
my $self = shift;
|
|
my $session = $self->session;
|
|
my $baseMessage = shift;
|
|
my $user = shift || $session->user;
|
|
|
|
my $sql = $self->getMessageSql($user,{
|
|
whereClause => "ibox.dateStamp > ".$baseMessage->get("dateStamp"),
|
|
sortBy => "ibox.dateStamp",
|
|
sortDir => "asc",
|
|
limit => 1
|
|
});
|
|
|
|
my $message = $self->session->db->quickHashRef($sql);
|
|
|
|
return $self->getMessage($message->{messageId});
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getPreviousMessage ( message [, userId] )
|
|
|
|
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.
|
|
|
|
=head3 user
|
|
|
|
The WebGUI::User object of the user to retrieve the message for. Defaults to the current user.
|
|
|
|
=cut
|
|
|
|
sub getPreviousMessage {
|
|
my $self = shift;
|
|
my $session = $self->session;
|
|
my $baseMessage = shift;
|
|
my $user = shift || $session->user;
|
|
|
|
my $sql = $self->getMessageSql($user,{
|
|
whereClause => "ibox.dateStamp < ".$baseMessage->get("dateStamp"),
|
|
sortBy => "ibox.dateStamp",
|
|
sortDir => "desc",
|
|
limit => 1
|
|
});
|
|
|
|
my $message = $self->session->db->quickHashRef($sql);
|
|
|
|
return $self->getMessage($message->{messageId});
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getMessagesForUser ( user [ , limit, page, sortBy ] )
|
|
|
|
Returns an array reference containing the most recent message objects for a given user.
|
|
|
|
=head3 user
|
|
|
|
A user object.
|
|
|
|
=head3 limit
|
|
|
|
An integer indicating the number of messages to fetch. Defaults to 50.
|
|
|
|
=head3 page
|
|
|
|
An integer indication the page to return. Defaults to 1
|
|
|
|
=head3 sortby
|
|
|
|
The column to sort by
|
|
|
|
=head3 where
|
|
|
|
An extra clause for filtering results.
|
|
|
|
=cut
|
|
|
|
sub getMessagesForUser {
|
|
my $self = shift;
|
|
my $user = shift;
|
|
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,
|
|
whereClause => $where,
|
|
});
|
|
|
|
return $self->getMessagesOnPage($p);
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getMessagesOnPage ( paginator )
|
|
|
|
Returns an array ref of WebGUI::Inbox::Message objects created from the current
|
|
page of data.
|
|
|
|
=head3 paginator
|
|
|
|
The id of the message to retrieve.
|
|
|
|
=cut
|
|
|
|
sub getMessagesOnPage {
|
|
my $self = shift;
|
|
my $p = shift;
|
|
my @messages = ();
|
|
|
|
unless (defined $p and ref $p eq "WebGUI::Paginator") {
|
|
$self->session->log->warn("Paginator was not defined");
|
|
return [];
|
|
}
|
|
|
|
foreach my $row (@{$p->getPageData}) {
|
|
push @messages, $self->getMessage( $row->{messageId} );
|
|
}
|
|
|
|
return \@messages;
|
|
}
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getMessagesPaginator ( user [, properties ] )
|
|
|
|
Returns an reference to a WebGUI::Paginator object filled with all the messages in a user's inbox
|
|
|
|
=head3 user
|
|
|
|
A user object.
|
|
|
|
=head3 properties
|
|
|
|
Properties which can be set to determine how many rows are returned, etc
|
|
|
|
=head4 sortBy
|
|
|
|
Column to sort the inbox by. Valid values are subject, sentBy, and dateStamp. Defaults to
|
|
dateStamp if value is invalid. Defaults to status DESC, dateStamp DESC if value not set.
|
|
|
|
=head4 sortDir
|
|
|
|
Direction to sort the results by. Defaults to desc. This only works if a sortBy value is set.
|
|
|
|
=head4 baseUrl
|
|
|
|
The URL of the current page including attributes. The page number will be appended to this in all links generated by the paginator.
|
|
Defaults to $session->url->pge
|
|
|
|
=head4 paginateAfter
|
|
|
|
The number of rows to display per page. If left blank it defaults to 25.
|
|
|
|
=head4 formVar
|
|
|
|
Specify the form variable the paginator should use in its links. Defaults to "pn".
|
|
|
|
=head4 pageNumber
|
|
|
|
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 {
|
|
my $self = shift;
|
|
my $session = $self->session;
|
|
my $user = shift || $session->user;
|
|
my $properties = shift;
|
|
|
|
my $userId = $user->userId;
|
|
my $sortBy = $properties->{sortBy};
|
|
my $sortDir = $properties->{sortDir} || "desc";
|
|
my $baseUrl = $properties->{baseUrl} || $session->url->page;
|
|
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 && !$sortBy ~~ [qw( subject sentBy dateStamp status )]) {
|
|
$sortBy = q{dateStamp}
|
|
}
|
|
#Sort by fullname if user wants to sort by who sent the message
|
|
if ($sortBy eq "sentBy") {
|
|
$sortBy = q{fullName};
|
|
}
|
|
elsif ($sortBy eq "status") {
|
|
$sortBy = q{messageStatus};
|
|
}
|
|
elsif($sortBy) {
|
|
$sortBy = qq{ibox.$sortBy};
|
|
}
|
|
else {
|
|
$sortBy = q{messageStatus='pending' DESC, dateStamp DESC};
|
|
$sortDir = q{};
|
|
}
|
|
|
|
my $sql = $self->getMessageSql($user, {
|
|
user => $user,
|
|
sortBy => $sortBy,
|
|
sortDir => $sortDir,
|
|
whereClause => $whereClause,
|
|
});
|
|
|
|
my $p = WebGUI::Paginator->new(
|
|
$session,
|
|
$baseUrl,
|
|
$paginateAfter,
|
|
$formVar,
|
|
$pageNumber
|
|
);
|
|
|
|
$p->setDataByQuery($sql,undef,undef);
|
|
|
|
return $p;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getMessageSql ( user, properties )
|
|
|
|
Returns the SQL used to return the messages in a user's inbox.
|
|
|
|
=head3 user
|
|
|
|
WebGUI::User object of user to get messages for. Defaults to current user.
|
|
|
|
=head3 properties
|
|
|
|
Hash reference of properties
|
|
|
|
=head4 sortBy
|
|
|
|
Column to sort by. Valid columns are:
|
|
|
|
ibox.messageId,
|
|
ibox.subject,
|
|
ibox.sentBy,
|
|
ibox.dateStamp,
|
|
ibox.status,
|
|
messageStatus,
|
|
fullName
|
|
|
|
=head4 sortDir
|
|
|
|
Direction to sort by
|
|
|
|
=head4 whereClause
|
|
|
|
A where clause to use
|
|
|
|
=head4 limit
|
|
|
|
A full limit clause, not just the number to limit.
|
|
|
|
=cut
|
|
|
|
sub getMessageSql {
|
|
my $self = shift;
|
|
my $session = $self->session;
|
|
my $user = shift || $session->user;
|
|
my $props = shift || {};
|
|
|
|
my $userId = $user->userId;
|
|
my $sortBy = $props->{sortBy};
|
|
my $sortDir = $props->{sortDir};
|
|
my $whereClause = $props->{whereClause};
|
|
my $limit = $props->{limit};
|
|
my $select = $props->{'select'};
|
|
|
|
if($sortBy) {
|
|
$sortBy = qq{ORDER BY $sortBy $sortDir};
|
|
}
|
|
|
|
if($whereClause) {
|
|
$whereClause = qq{AND $whereClause};
|
|
}
|
|
|
|
if($limit) {
|
|
$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(users.firstName != '' and users.firstName is not null and users.lastName !='' and users.lastName is not null, concat(users.firstName,' ',users.lastName),users.username)) as fullName
|
|
SELECT
|
|
}
|
|
|
|
my $sql = qq{
|
|
SELECT
|
|
$select
|
|
FROM inbox_messageState
|
|
JOIN inbox ibox USING (messageId)
|
|
LEFT OUTER JOIN users on users.userId = ibox.sentBy
|
|
LEFT OUTER JOIN userProfileData on userProfileData.userId = ibox.sentBy
|
|
WHERE inbox_messageState.messageId = ibox.messageId
|
|
AND inbox_messageState.userId = '$userId'
|
|
AND inbox_messageState.deleted = 0
|
|
$whereClause
|
|
$sortBy
|
|
$limit
|
|
};
|
|
|
|
#$session->log->warn($sql);
|
|
|
|
return $sql;
|
|
}
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getUnreadMessageCount ( [userId] )
|
|
|
|
Returns the number of unread messages for the user passed in
|
|
|
|
=head3 userId
|
|
|
|
user to get unread message count for. Defaults to current user.
|
|
|
|
=cut
|
|
|
|
sub getUnreadMessageCount {
|
|
my $self = shift;
|
|
my $session = $self->session;
|
|
my $userId = shift || $session->user->userId;
|
|
|
|
return $session->db->quickScalar(
|
|
qq{select count(*) from inbox_messageState where userId=? and deleted=0 and isRead=0 },
|
|
[$userId]
|
|
);
|
|
}
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 new ( session )
|
|
|
|
Constructor.
|
|
|
|
=head3 session
|
|
|
|
A reference to the current session.
|
|
|
|
=cut
|
|
|
|
sub new {
|
|
my $class = shift;
|
|
my $session = shift;
|
|
bless {_session=>$session}, $class;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 session ( )
|
|
|
|
Returns a reference to the current session.
|
|
|
|
=cut
|
|
|
|
sub session {
|
|
my $self = shift;
|
|
return $self->{_session};
|
|
}
|
|
|
|
|
|
1;
|