collect-reminders also contains the year number
[email-reminder.git] / EmailReminder / Event.pm
blobb05986ed9a752f30d2912f4f8383f14075b0f7eb
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;
62 # other XML tags, attributes and values
63 my $REMINDER_TAG = 'reminder';
64 my $REMINDERS_TAG = 'reminders';
65 my $RECIPIENT_TAG = 'recipient';
66 my $RECIPIENTS_TAG = 'recipients';
68 my $EMAIL_ATTR = 'email';
69 my $NAME_ATTR = 'name';
70 my $TYPE_ATTR = 'type';
72 my $DAYS_BEFORE_VAL = 'days before';
73 my $SAME_DAY_VAL = 'same day';
75 # Hard-coded value for this event's type (class method)
76 sub get_type
78 return;
81 # Number of fields this event adds to its parent (class method)
82 sub get_nb_fields
84 return 1;
87 sub valid_name {
88 my ($class, $new_value) = @_;
89 return $new_value;
92 sub new
94 my $class = shift;
95 my $event_node = shift;
96 my $id = shift;
98 my $self = { "OCCURRING" => 0,
99 "XML_NODE" => $event_node,
100 "ID" => $id,
101 "DATA" => [$id],
104 bless $self, $class;
106 # Create empty data array
107 my $count = $self->get_nb_fields() - 1;
108 for (my $i = 0; $i < $count; $i++) {
109 push(@{$self->{DATA}}, undef);
112 # Where to send this reminder email
113 my $recipients = $self->{XML_NODE}->getElementsByTagName($RECIPIENTS_TAG)->item(0);
114 if (defined($recipients)) {
115 $self->{RECIPIENTS_NODE} = $recipients;
116 $self->{RECIPIENTS_CACHE} = $self->get_recipients();
119 # Process reminders
120 my $reminders = $self->{XML_NODE}->getElementsByTagName($REMINDERS_TAG)->item(0);
121 if (defined($reminders)) {
122 $self->{REMINDERS_NODE} = $reminders;
123 $self->{REMINDERS_CACHE} = $self->get_reminders();
126 return $self;
129 sub unlink
131 my $self = shift;
132 my $node = $self->{XML_NODE};
133 $node->getParentNode()->removeChild($node);
134 $node->dispose();
137 sub get_recipients
139 my $self = shift;
141 if (!defined($self->{RECIPIENTS_CACHE})) {
142 my @recipients = ();
144 if (defined($self->{RECIPIENTS_NODE})) {
145 foreach my $recipient ($self->{RECIPIENTS_NODE}->getElementsByTagName($RECIPIENT_TAG)) {
146 my $email = $recipient->getAttribute($EMAIL_ATTR);
147 if (defined($email)) {
148 my $fname = undef;
149 my $lname = undef;
150 my $fullname = $recipient->getAttribute($NAME_ATTR);
152 my @name_parts = split(/ /, $fullname);
153 $fname = $name_parts[0];
154 $lname = $name_parts[-1] if @name_parts > 1;
156 push(@recipients, [$email, $fname, $lname]);
161 $self->{RECIPIENTS_CACHE} = \@recipients;
163 return $self->{RECIPIENTS_CACHE};
166 sub get_reminders
168 my $self = shift;
170 if (!defined($self->{REMINDERS_CACHE})) {
171 my @reminders = ();
173 if (defined($self->{REMINDERS_NODE}))
175 foreach my $reminder ($self->{REMINDERS_NODE}->getElementsByTagName($REMINDER_TAG)){
176 my $type = $reminder->getAttribute($TYPE_ATTR);
178 if ($type eq $SAME_DAY_VAL) {
179 push(@reminders, 0);
181 if ($self->will_occur("")) {
182 $self->{WHEN} = "today";
183 $self->{OCCURRING}++;
186 elsif (($type eq $DAYS_BEFORE_VAL) &&
187 ($reminder->getFirstChild()))
189 my $days = $reminder->getFirstChild()->getNodeValue();
190 push(@reminders, $days);
192 if ($self->will_occur($days)) {
193 if ($days > 1) {
194 my $upcoming_date = DateCalc("today", "+${days}days");
195 $self->{WHEN} = "in $days days (" . UnixDate($upcoming_date, "%A %b %e") . ")";
197 elsif ($days == 1) {
198 $self->{WHEN} = "tomorrow";
200 elsif ($days == 0) {
201 $self->{WHEN} = "today";
203 else {
204 next; # Negative days are ignored
207 $self->{OCCURRING}++;
213 $self->{REMINDERS_CACHE} = \@reminders;
216 return $self->{REMINDERS_CACHE};
219 sub set_reminders
221 my ($self, $new_reminders) = @_;
223 my $event = $self->{XML_NODE};
224 my $doc = $event->getOwnerDocument();
225 my $reminders = $self->{REMINDERS_NODE};
227 if (!defined($reminders)) {
228 # Create a blank <reminders> tag
229 $reminders = $doc->createElement($REMINDERS_TAG);
230 $event->appendChild($reminders);
232 $self->{REMINDERS_NODE} = $reminders;
234 else {
235 # TODO: preserve extra reminders in the XML but not in the UI
237 # Delete all current reminders
238 foreach my $child ($reminders->getChildNodes()) {
239 $reminders->removeChild($child);
243 # Add all reminders to the <reminders> node
244 foreach my $nb_days (@$new_reminders)
246 my $new_node = $doc->createElement($REMINDER_TAG);
248 if ($nb_days == 0)
250 $new_node->setAttribute($TYPE_ATTR, $SAME_DAY_VAL);
252 elsif ($nb_days > 0)
254 $new_node->setAttribute($TYPE_ATTR, $DAYS_BEFORE_VAL);
255 $new_node->addText($nb_days);
257 else
259 # Invalid number, ignore
260 next;
263 $reminders->appendChild($new_node);
266 # Clear the cache
267 undef $self->{REMINDERS_CACHE};
270 sub is_occurring
272 my $self = shift;
273 return $self->{OCCURRING};
276 sub get_message
278 my $self = shift;
280 # destination user
281 my $first_name = shift || 'there';
283 my $body = $self->get_message_body(@_);
285 my $message = "";
286 $message = <<"MESSAGEEND" if $body;
287 Hi $first_name,
289 $body
290 Have a good day!
293 Sent by Email-Reminder $EmailReminder::Utils::VERSION
294 http://www.email-reminder.org.nz/
295 MESSAGEEND
297 return $message;
300 sub data
302 my $self = shift;
303 return $self->{DATA};
306 sub get_id
308 my $self = shift;
309 return $self->{ID};