3 # Copyright Liblime 2009
4 # Copyright Catalyst IT 2012
6 # This file is part of Koha.
8 # Koha is free software; you can redistribute it and/or modify it
9 # under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 3 of the License, or
11 # (at your option) any later version.
13 # Koha is distributed in the hope that it will be useful, but
14 # WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with Koha; if not, see <http://www.gnu.org/licenses>.
31 C4::Message - object for messages in the message_queue table
35 How to add a new message to the queue:
39 my $borrower = { borrowernumber => 1 };
40 my $item = C4::Items::GetItem(1);
41 my $letter = C4::Letters::GetPreparedLetter (
42 module => 'circulation',
43 letter_code => 'CHECKOUT',
44 branchcode => $branch,
46 'biblio', $item->{biblionumber},
47 'biblioitems', $item->{biblionumber},
50 C4::Message->enqueue($letter, $borrower->{borrowernumber}, 'email');
52 How to update a borrower's last checkout message:
55 my $borrower = { borrowernumber => 1 };
56 my $message = C4::Message->find_last_message($borrower, 'CHECKOUT', 'email');
57 $message->append("you also checked out some other book....");
62 This module presents an OO interface to the message_queue. Previously,
63 you could only add messages to the message_queue via
64 C<C4::Letters::EnqueueMessage()>. With this module, you can also get
65 previously inserted messages, manipulate them, and save them back to the
76 =head3 C4::Message->new(\%attributes)
78 This method creates an in-memory version of a message object.
82 # C4::Message->new(\%attributes) -- constructor
84 my ($class, $opts) = @_;
86 bless {%$opts} => $class;
90 =head3 C4::Message->find($id)
92 This method searches the message_queue table for a row with the given
93 C<message_id> and it'll return a C4::Message object if it finds one.
97 # C4::Message->find($id) -- find a message by its message_id
99 my ($class, $id) = @_;
100 my $dbh = C4
::Context
->dbh;
101 my $msgs = $dbh->selectall_arrayref(
102 qq{SELECT
* FROM message_queue WHERE message_id
= ?
},
107 return $class->new($msgs->[0]);
113 =head3 C4::Message->find_last_message($borrower, $letter_code, $transport)
115 This method is used to get the borrower's most recent, pending, check-in or
116 checkout message. (This makes it possible to add more information to the
117 message before it gets sent out.)
121 # C4::Message->find_last_message($borrower, $letter_code, $transport)
122 # -- get the borrower's most recent pending checkin or checkout notification
123 sub find_last_message
{
124 my ($class, $borrower, $letter_code, $transport) = @_;
125 # $type is the message_transport_type
126 $transport ||= 'email';
127 my $dbh = C4
::Context
->dbh;
128 my $msgs = $dbh->selectall_arrayref(
132 WHERE status
= 'pending'
133 AND borrowernumber
= ?
135 AND message_transport_type
= ?
138 $borrower->{borrowernumber
},
143 return $class->new($msgs->[0]);
150 =head3 C4::Message->enqueue($letter, $borrower, $transport)
152 This is a front-end for C<C4::Letters::EnqueueLetter()> that adds metadata to
157 # C4::Message->enqueue($letter, $borrower, $transport)
159 my ($class, $letter, $borrower, $transport) = @_;
160 my $metadata = _metadata
($letter);
161 my $to_address = _to_address
($borrower, $transport);
163 # Same as render_metadata
164 my $format ||= sub { $_[0] || "" };
165 my $body = join('', map { $format->($_) } @
{$metadata->{body
}});
166 $letter->{content
} = $metadata->{header
} . $body . $metadata->{footer
};
168 $letter->{metadata
} = Dump
($metadata);
169 C4
::Letters
::EnqueueLetter
({
171 borrowernumber
=> $borrower->{borrowernumber
},
172 message_transport_type
=> $transport,
173 to_address
=> $to_address,
177 # based on message $transport, pick an appropriate address to send to
179 my ($borrower, $transport) = @_;
181 if ($transport eq 'email') {
182 $address = $borrower->{email
}
183 || $borrower->{emailpro
}
184 || $borrower->{B_email
};
185 } elsif ($transport eq 'sms') {
186 $address = $borrower->{smsalertnumber
}
187 || $borrower->{phone
}
188 || $borrower->{phonepro
}
189 || $borrower->{B_phone
};
191 warn "'$transport' is an unknown message transport.";
193 if (not defined $address) {
194 warn "An appropriate $transport address "
195 . "for borrower $borrower->{userid} "
196 . "could not be found.";
201 # _metadata($letter) -- return the letter split into head/body/footer
204 if ($letter->{content
} =~ /----/) {
205 my ($header, $body, $footer) = split(/----\r?\n?/, $letter->{content
});
214 body
=> [$letter->{content
}],
220 =head2 Instance Methods
222 =head3 $message->update()
224 This saves the $message object back to the database. It needs to have
225 already been created via C<enqueue> for this to work.
229 # $object->update -- save object to database
232 my $dbh = C4
::Context
->dbh;
242 message_transport_type
= ?
,
251 $self->borrowernumber,
254 $self->{metadata
}, # we want the raw YAML here
256 $self->message_transport_type,
266 =head3 $message->metadata(\%new_metadata)
268 This method automatically serializes and deserializes the metadata
269 attribute. (It is stored in YAML format.)
273 # $object->metadata -- this is a YAML serialized column that contains a
274 # structured representation of $object->content
276 my ($self, $data) = @_;
278 $data->{header
} ||= '';
279 $data->{body
} ||= [];
280 $data->{footer
} ||= '';
281 $self->{metadata
} = Dump
($data);
282 $self->content($self->render_metadata);
285 return Load
($self->{metadata
});
289 # turn $object->metadata into a string suitable for $object->content
290 sub render_metadata
{
291 my ($self, $format) = @_;
292 $format ||= sub { $_[0] || "" };
293 my $metadata = $self->metadata;
294 my $body = $metadata->{body
};
295 my $text = join('', map { $format->($_) } @
$body);
296 return $metadata->{header
} . $text . $metadata->{footer
};
299 =head3 $message->append(\%letter)
301 If passed a hashref, this method will assume that the hashref is in the form
302 that C<C4::Letters::getletter()> returns. It will append the body of the
303 letter to the message.
305 =head3 $message->append($string)
307 If passed a string, it'll append the string to the message.
311 # $object->append($letter_or_item) -- add a new item to a message's content
313 my ($self, $letter_or_item, $format) = @_;
314 my ( $item, $header, $footer );
315 if (ref($letter_or_item)) {
316 my $letter = $letter_or_item;
317 my $metadata = _metadata
($letter);
318 $header = $metadata->{header
};
319 $footer = $metadata->{footer
};
320 $item = $metadata->{body
}->[0];
322 $item = $letter_or_item;
324 if (not $self->metadata) {
325 carp
"Can't append to messages that don't have metadata.";
328 my $metadata = $self->metadata;
329 push @
{$metadata->{body
}}, $item;
330 $metadata->{header
} = $header;
331 $metadata->{footer
} = $footer;
332 $self->metadata($metadata);
333 my $new_content = $self->render_metadata($format);
334 return $self->content($new_content);
337 =head2 Attributes Accessors
339 =head3 $message->message_id
343 =head3 $message->borrowernumber
347 =head3 $message->subject
351 =head3 $message->content
355 =head3 $message->metadata
359 =head3 $message->letter_code
363 =head3 $message->message_transport_type
367 =head3 $message->status
371 =head3 $message->time_queued
375 =head3 $message->to_address
379 =head3 $message->from_address
383 =head3 $message->content_type
387 # $object->$method -- treat keys as methods
389 my ($self, @args) = @_;
390 my $attr = $AUTOLOAD;
392 if (ref($self->{$attr}) eq 'CODE') {
393 $self->{$attr}->($self, @args);
396 $self->{$attr} = $args[0];
409 L<C4::Circulation>, L<C4::Letters>, L<C4::Members::Messaging>
413 John Beppu <john.beppu@liblime.com>