Apache-App-Mercury
view release on metacpan or search on metacpan
my $q = $self->{q};
my $controller = $self->{controller};
my %args = $self->{r}->args;
# set up and preparation - independent of page
$self->get_mailboxes;
my $box = $self->{'current_box'} = $self->get_current_mailbox;
my $need_sort;
if ($args{$box.'_sortby'} and
$args{$box.'_sortby'} ne ($self->{$box}->{'sortby'} .
($self->{$box}->{'sortdir'}
? '__'.$self->{$box}->{'sortdir'} : ''))) {
my ($sort, $updown) = split('__', $args{$box.'_sortby'});
$need_sort = $self->set_sortby(undef, $sort, $updown);
} elsif (!$self->{$box}->{'sortby'}) {
$need_sort = $self->set_sortby;
}
# hit database if user wants or if more than 10 minutes has past since last
if ($q->param('check_mail') or !$self->{'last_mail_check'} or
$controller->get_time > $self->{'last_mail_check'}+600) {
$self->check_mail;
$need_sort = 0; # since mail checking automtically sorts
}
# cannot sort until boxes are made (by checkmail)
# but only sort if sortby was changed and mail was not checked
$self->sort_mailbox if $need_sort;
# actions, non-displaying
if ($q->param('delete')) {
$self->delete_messages;
} elsif ($q->param('transfer')) {
$self->transfer_messages;
}
# change state if we're now trying to view messages in an empty mailbox
$self->{'state'} = 'message_center'
if ($self->{'state'} eq 'view_messages' and
$#{$self->{$box}->{'index'}} < 0);
# outputting and page creation
if ($q->param('cancel')) {
$self->cancel_operation;
$self->{'state'} = 'message_center';
$self->show_mail_center;
$controller->sitemark('/messaging');
} elsif ($q->param('message_center')) {
$self->{'state'} = 'message_center';
$self->show_mail_center;
$controller->sitemark('/messaging');
} elsif ($self->{'state'} eq 'edit_settings' or $args{'edit_mail_prefs'}) {
if ($q->param('add_box')) {
if ($self->verify_new_mailbox($q->param('new_box'))) {
$self->add_new_mailbox($q->param('new_box'));
$self->checkmail;
$q->delete('new_box');
}
} elsif ($q->param('delete_box')) {
$self->delete_mailbox($q->param('custom_box'),
$q->param('delete_mail_in_box'));
$self->checkmail;
$q->delete('custom_box');
$q->delete('delete_mail_in_box');
} elsif ($q->param('commit_filter')) {
$self->edit_filters;
$self->checkmail;
# $q->delete('trans_filter');
} elsif ($q->param('update_auto_forward')) {
$self->update_auto_forward;
$self->checkmail;
}
$self->{'state'} = 'edit_settings';
$self->show_mail_settings;
$controller->sitemark('/messaging.settings');
} elsif ($self->{'state'} eq 'compose_message') {
$self->save_compose_message_fields;
$controller->sitemark('/messaging.compose');
$controller->infomsg("You must take action on your existing composition before creating a transaction-related message.")
if ($q->param('reply_trans') or $q->param('compose_trans'));
if ($q->param('preview')) {
my ($fail, $recip, $recip_desc) =
$self->verify_recipient($self->{compose_msg}->{'sent_to'}, 1);
unless ($fail) {
$self->{compose_msg}->{'sent_to'} = $recip;
$self->{compose_msg}->{'recipient_desc'} = $recip_desc;
$self->{'state'} = 'preview_message';
$self->show_mail_preview;
$controller->sitemark('/messaging.preview');
return;
}
} elsif ($q->param('return')) {
$controller->infomsg("Your composition has been saved in memory. It will be removed when you log out.");
$self->{'state'} = 'message_center';
$self->show_mail_center;
$controller->sitemark('/messaging');
return;
} elsif ($q->param('reset')) {
$self->reset_compose_message;
} elsif ($q->param('change_recip')) {
$self->{compose_msg}->{'action'} .= "-changed_recip";
} elsif ($q->param('memo')) {
$self->{compose_msg}->{'sent_to'} = $self->{user_manager}->userprofile('user');
$self->{compose_msg}->{'recipient_desc'} = $self->{user_manager}->userprofile('user_desc');
} elsif ($q->param('nonmemo')) {
$self->{compose_msg}->{'sent_to'} = '';
$self->{compose_msg}->{'recipient_desc'} = '';
} elsif (defined (my $attach_no = $q->param('remove_attach'))) {
splice(@{$self->{compose_msg}->{'Attachments'}}, $attach_no, 1);
}
$self->show_mail_compose;
} elsif ($self->{'state'} eq 'preview_message') {
$self->save_compose_message_fields;
$controller->sitemark('/messaging.preview');
$controller->infomsg("You must take action on your existing composition before creating a transaction-related message.")
if ($q->param('reply_trans') or $q->param('compose_trans'));
if ($q->param('send')) {
$self->{'state'} = 'message_center';
$self->message_send;
$self->check_mail;
$self->show_mail_center;
$controller->sitemark('/messaging');
} elsif ($q->param('make_changes')) {
}
return 1;
}
sub add_new_mailbox {
my ($self, $new_box) = @_;
my $controller = $self->{controller};
my $user = $self->{user_manager}->userprofile('user');
my @old_boxes = $self->{user_manager}->mailboxes;
if ($#old_boxes == 14) {
$controller->infomsg("You already have 15 custom mailboxes, which is the maximum currently allowed.");
return;
}
push(@old_boxes, $new_box);
if ($self->{user_manager}->mailboxes($user, @old_boxes)) {
$controller->infomsg("Mailbox ".ucfirst($new_box)." has been created.");
}
}
sub delete_mailbox {
my ($self, $old_box, $delete_mail_in_box) = @_;
my $controller = $self->{controller};
my $user = $self->{user_manager}->userprofile('user');
my $num_displaced = $#{$self->{$old_box}->{'index'}} + 1;
# get rid of filters, if necessary
$self->remove_filters_for($old_box);
# then move out the mail
if ($delete_mail_in_box) {
$self->change_status(undef, 'deleted', $old_box);
} else {
$self->change_box('inbox', $old_box);
}
my @boxes = $self->{user_manager}->mailboxes;
@boxes = grep($_ ne $old_box, @boxes);
if ($self->{user_manager}->mailboxes($user, @boxes)) {
delete $self->{$old_box};
# if mail has been transfered to inbox, rebuild it
# - doesn't seem to work otherwise . . .
if (!$delete_mail_in_box) {
my ($sortby, $sortdir) = $self->get_sortby('inbox');
delete $self->{'inbox'};
$self->set_sortby('inbox', $sortby, $sortdir);
$self->makebox('inbox');
}
$self->{'current_box'} = 'inbox' if $self->{'current_box'} eq $old_box;
$controller->infomsg(ucfirst($old_box)." has been deleted".($delete_mail_in_box ? " along with the $num_displaced messages stored there." : ". The $num_displaced messages stored there have been moved to your Inbox."));
}
}
sub edit_filters {
my ($self) = @_;
my $q = $self->{q};
if ($q->param('trans_filter') and
$q->param('trans_filter') ne $self->{user_manager}->mail_trans_filter) {
$self->{user_manager}->mail_trans_filter($q->param('trans_filter'));
}
}
sub remove_filters_for {
my ($self, $old_box) = @_;
# this is the only filter, add filter checks as filters are created
if ($self->{user_manager}->mail_trans_filter eq $old_box) {
# set transaction filter back to 'inbox'
unless ($self->{user_manager}->mail_trans_filter('inbox')) {
$self->warn("->remove_filters_for($old_box) FAILED!");
}
}
}
sub update_auto_forward {
my ($self) = @_;
my $q = $self->{q};
$self->{user_manager}->auto_forward('low', $q->param('forward_low'));
$self->{user_manager}->auto_forward('medium', $q->param('forward_medium'));
$self->{user_manager}->auto_forward('high', $q->param('forward_high'));
}
sub count_unread {
my ($self, $user, $this_box, $force_db) = @_;
my $no_need_db;
if (!$force_db and $self->{'mailboxes'}) {
my $cnt = 0;
my $this_cnt = 0;
foreach my $box (@{$self->{'mailboxes'}}) {
if ($box ne 'outbox' and
ref $self->{$box}->{'msgs'} eq 'HASH' and
ref $self->{$box}->{'index'} eq 'ARRAY') {
$no_need_db = 1;
foreach (@{$self->{$box}->{'index'}}) {
my $msg = $self->{$box}->{'msgs'}->{$_};
$cnt++ if ($msg->{'status'} eq 'unread' and
$msg->{'recipient'} ne $msg->{'sender'});
$this_cnt++ if ($box eq $this_box and
$msg->{'status'} eq 'unread' and
$msg->{'recipient'} ne $msg->{'sender'});
}
}
}
if ($no_need_db) {
if ($this_box) {
return ($cnt, $this_cnt);
} else {
return $cnt;
}
}
}
# only use database if forced or if there's no legitimate mailboxes
if ($force_db or !$no_need_db) {
$user = $self->{user_manager}->userprofile('user') if !$user;
return $self->dbi_count_unread($user);
}
}
1;
__END__
=head1 NAME
Apache::App::Mercury - Internal web messaging for Apache mod_perl (1.x)
=head1 SYNOPSIS
# first, edit Apache/App/Mercury/Config.pm and set variables appropriately
# from the mod_perl handler of your application
# Note: in these examples My::MVC::Controller is assumed to be a class
# which provides a persistence framework so object variables are kept
# across http requests; it also must implement some predefined methods
# (see below for details on these methods)
$controller = My::MVC::Controller->new;
$controller->handler;
...
# My::MVC::Controller top-level control method (e.g. handler())
sub handler {
my $self = my $controller = shift;
...
if ($r->uri eq Apache::App::Mercury::Config::BASE_URI()) {
$controller->{wm} = Apache::App::Mercury->new
$controller->{wm}->initialize($controller);
$controller->{wm}->content_handler;
$controller->{wm}->cleanup;
}
...
# $r is an Apache->request object
$r->content_type("text/html");
$r->send_http_header;
$r->print("<HTML><HEAD><TITLE>".$controller->pagetitle."</TITLE></HEAD>".
"<BODY>".$controller->pagebody."</BODY></HTML>");
}
### === --<>-- === ###
# to generate a message from 'sender_user' to 'recipient_user' with a
# security-level setting of 'low' (security => 'low'), and without
# storing a copy of the message in the sender's Outbox (nocopy => 1)
Apache::App::Mercury::Message->new
({ 'sent_to' => 'recipient_user', 'sender' => 'sender_user',
'subject' => "Subject line ...", 'nocopy' => 1, 'security' => 'low',
'body' => "Message body\nline 2\nline 3\n...\n" })
->store;
=head1 MYTHOLOGY
Mercury the swift messenger of the ancient gods.
The Greek god Hermes (the Roman Mercury) was the god of translators and
interpreters. He was the most clever of the Olympian gods, and served as
messenger for all the other gods. He ruled over wealth, good fortune, commerce,
fertility, and thievery.
Among his personal favorite commercial activities was the corn trade. He was
also the god of manual arts and eloquence. As the deity of athletes, he
protected gymnasiums and stadiums.
=head1 DESCRIPTION
Apache::App::Mercury is a customizable, extensible customer to customer,
store and forward messaging application for Apache mod_perl (1.x).
It might be useful if you have a web application with many users who
login periodically, and you want to give each of them a "message box"
in which they can receive auto-generated messages, or communicate with
each other. It uses a relational database (accessed via DBI) to store
( run in 0.544 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )