Update homepage URL and author email address
[email-reminder.git] / EmailReminder / Event.pm
blob0f3a021188d2cc54960a34c9b69eafe3c8bc9ca8
1 # This file is part of Email-Reminder.
3 # Email-Reminder is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License as
5 # published by the Free Software Foundation; either version 3 of the
6 # License, or (at your option) any later version.
8 # Email-Reminder is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 # General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with Email-Reminder; if not, write to the Free Software
15 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 # 02110-1301, USA.
18 package EmailReminder::Event;
20 # Base class for all other events.
22 # This class should never be used directly, use a derived class instead.
24 use strict;
25 use warnings;
27 use Date::Manip;
28 use XML::DOM;
30 use EmailReminder::Utils;
32 # XML tags
33 __PACKAGE__->mk_accessors(qw(name));
35 sub mk_accessors {
36 my ($self, @field_names) = @_;
38 # get the classname since it might be a derived class calling this
39 my $class = ref $self || $self;
41 foreach my $field_name ( @field_names ) {
42 my $get_method = sub {
43 my ($self) = @_;
44 my $valid_sub = "valid_$field_name";
45 my $value = EmailReminder::Utils::get_node_value($self->{XML_NODE}, $field_name);
46 return $self->$valid_sub( $value );
49 my $set_method = sub {
50 my ($self, $new_value) = @_;
51 return EmailReminder::Utils::set_node_value($self->{XML_NODE}, $field_name, $new_value);
55 no strict 'refs';
56 *{"${class}::get_$field_name"} = $get_method;
57 *{"${class}::set_$field_name"} = $set_method;
60 return 1;
63 # other XML tags, attributes and values
64 my $REMINDER_TAG = 'reminder';
65 my $REMINDERS_TAG = 'reminders';
66 my $RECIPIENT_TAG = 'recipient';
67 my $RECIPIENTS_TAG = 'recipients';
69 my $EMAIL_ATTR = 'email';
70 my $NAME_ATTR = 'name';
71 my $TYPE_ATTR = 'type';
73 my $DAYS_BEFORE_VAL = 'days before';
74 my $SAME_DAY_VAL = 'same day';
76 # Hard-coded value for this event's type (class method)
77 sub get_type
79 return;
82 # Number of fields this event adds to its parent (class method)
83 sub get_nb_fields
85 return 1;
88 sub valid_name {
89 my ($class, $new_value) = @_;
90 return $new_value;
93 sub new
95 my $class = shift;
96 my $event_node = shift;
97 my $id = shift;
99 my $self = { "OCCURRING" => 0,
100 "XML_NODE" => $event_node,
101 "ID" => $id,
102 "DATA" => [$id],
105 bless $self, $class;
107 # Create empty data array
108 my $count = $self->get_nb_fields() - 1;
109 for (my $i = 0; $i < $count; $i++) {
110 push(@{$self->{DATA}}, undef);
113 # Where to send this reminder email
114 my $recipients = $self->{XML_NODE}->getElementsByTagName($RECIPIENTS_TAG)->item(0);
115 if (defined($recipients)) {
116 $self->{RECIPIENTS_NODE} = $recipients;
117 $self->{RECIPIENTS_CACHE} = $self->get_recipients();
120 # Process reminders
121 my $reminders = $self->{XML_NODE}->getElementsByTagName($REMINDERS_TAG)->item(0);
122 if (defined($reminders)) {
123 $self->{REMINDERS_NODE} = $reminders;
124 $self->{REMINDERS_CACHE} = $self->get_reminders();
127 return $self;
130 sub unlink_event
132 my $self = shift;
133 my $node = $self->{XML_NODE};
134 $node->getParentNode()->removeChild($node);
135 $node->dispose();
136 return 1;
139 sub get_recipients
141 my $self = shift;
143 if (!defined($self->{RECIPIENTS_CACHE})) {
144 my @recipients = ();
146 if (defined($self->{RECIPIENTS_NODE})) {
147 foreach my $recipient ($self->{RECIPIENTS_NODE}->getElementsByTagName($RECIPIENT_TAG)) {
148 my $email = $recipient->getAttribute($EMAIL_ATTR);
149 if (defined($email)) {
150 my $fname = undef;
151 my $lname = undef;
152 my $fullname = $recipient->getAttribute($NAME_ATTR);
154 my @name_parts = split(/ /, $fullname);
155 $fname = $name_parts[0];
156 $lname = $name_parts[-1] if @name_parts > 1;
158 push(@recipients, [$email, $fname, $lname]);
163 $self->{RECIPIENTS_CACHE} = \@recipients;
165 return $self->{RECIPIENTS_CACHE};
168 sub get_reminders
170 my $self = shift;
172 if (!defined($self->{REMINDERS_CACHE})) {
173 my @reminders = ();
175 if (defined($self->{REMINDERS_NODE}))
177 foreach my $reminder ($self->{REMINDERS_NODE}->getElementsByTagName($REMINDER_TAG)){
178 my $type = $reminder->getAttribute($TYPE_ATTR);
180 if ($type eq $SAME_DAY_VAL) {
181 push(@reminders, 0);
183 if ($self->will_occur("")) {
184 $self->{WHEN} = "today";
185 $self->{OCCURRING}++;
188 elsif (($type eq $DAYS_BEFORE_VAL) &&
189 ($reminder->getFirstChild()))
191 my $days = $reminder->getFirstChild()->getNodeValue();
192 push(@reminders, $days);
194 if ($self->will_occur($days)) {
195 if ($days > 1) {
196 my $upcoming_date = DateCalc("today", "+${days}days");
197 $self->{WHEN} = "in $days days (" . UnixDate($upcoming_date, "%A %b %e") . ")";
199 elsif ($days == 1) {
200 $self->{WHEN} = "tomorrow";
202 elsif ($days == 0) {
203 $self->{WHEN} = "today";
205 else {
206 next; # Negative days are ignored
209 $self->{OCCURRING}++;
215 $self->{REMINDERS_CACHE} = \@reminders;
218 return $self->{REMINDERS_CACHE};
221 sub set_reminders
223 my ($self, $new_reminders) = @_;
225 my $event = $self->{XML_NODE};
226 my $doc = $event->getOwnerDocument();
227 my $reminders = $self->{REMINDERS_NODE};
229 if (!defined($reminders)) {
230 # Create a blank <reminders> tag
231 $reminders = $doc->createElement($REMINDERS_TAG);
232 $event->appendChild($reminders);
234 $self->{REMINDERS_NODE} = $reminders;
236 else {
237 # TODO: preserve extra reminders in the XML but not in the UI
239 # Delete all current reminders
240 foreach my $child ($reminders->getChildNodes()) {
241 $reminders->removeChild($child);
245 # Add all reminders to the <reminders> node
246 foreach my $nb_days (@$new_reminders)
248 my $new_node = $doc->createElement($REMINDER_TAG);
250 if ($nb_days == 0)
252 $new_node->setAttribute($TYPE_ATTR, $SAME_DAY_VAL);
254 elsif ($nb_days > 0)
256 $new_node->setAttribute($TYPE_ATTR, $DAYS_BEFORE_VAL);
257 $new_node->addText($nb_days);
259 else
261 # Invalid number, ignore
262 next;
265 $reminders->appendChild($new_node);
268 # Clear the cache
269 undef $self->{REMINDERS_CACHE};
271 return 1;
274 sub is_occurring
276 my $self = shift;
277 return $self->{OCCURRING};
280 sub get_message
282 my $self = shift;
284 # destination user
285 my $first_name = shift || 'there';
287 my $body = $self->get_message_body(@_);
289 my $message = "";
290 $message = <<"MESSAGEEND" if $body;
291 Hi $first_name,
293 $body
294 Have a good day!
297 Sent by Email-Reminder $EmailReminder::Utils::VERSION
298 https://launchpad.net/email-reminder
299 MESSAGEEND
301 return $message;
304 sub data
306 my $self = shift;
307 return $self->{DATA};
310 sub get_id
312 my $self = shift;
313 return $self->{ID};