| File: | C4/Members/Messaging.pm |
| Coverage: | 12.8% |
| line | stmt | bran | cond | sub | time | code |
|---|---|---|---|---|---|---|
| 1 | package C4::Members::Messaging; | |||||
| 2 | ||||||
| 3 | # Copyright (C) 2008 LibLime | |||||
| 4 | # | |||||
| 5 | # This file is part of Koha. | |||||
| 6 | # | |||||
| 7 | # Koha is free software; you can redistribute it and/or modify it under the | |||||
| 8 | # terms of the GNU General Public License as published by the Free Software | |||||
| 9 | # Foundation; either version 2 of the License, or (at your option) any later | |||||
| 10 | # version. | |||||
| 11 | # | |||||
| 12 | # Koha is distributed in the hope that it will be useful, but WITHOUT ANY | |||||
| 13 | # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||||
| 14 | # A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||||
| 15 | # | |||||
| 16 | # You should have received a copy of the GNU General Public License along | |||||
| 17 | # with Koha; if not, write to the Free Software Foundation, Inc., | |||||
| 18 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |||||
| 19 | ||||||
| 20 | 15 15 15 | 18519 104 522 | use strict; | |||
| 21 | 15 15 15 | 215 187 791 | use warnings; | |||
| 22 | 15 15 15 | 292 71 288 | use C4::Context; | |||
| 23 | ||||||
| 24 | 15 15 15 | 163 63 840 | use vars qw($VERSION); | |||
| 25 | ||||||
| 26 | BEGIN { | |||||
| 27 | # set the version for version checking | |||||
| 28 | 15 | 17010 | $VERSION = 3.00; | |||
| 29 | } | |||||
| 30 | ||||||
| 31 - 57 | =head1 NAME
C4::Members::Messaging - manage patron messaging preferences
=head1 SYNOPSIS
use C4::Members::Messaging
=head1 DESCRIPTION
This module lets you modify a patron's messaging preferences.
=head1 FUNCTIONS
=head2 GetMessagingPreferences
my $preferences = C4::Members::Messaging::GetMessagingPreferences( { borrowernumber => $borrower->{'borrowernumber'},
message_name => 'DUE' } );
my $preferences = C4::Members::Messaging::GetMessagingPreferences( { categorycode => 'LIBRARY',
message_name => 'DUE' } );
returns: a hashref of messaging preferences for a borrower or patron category for a particlar message_name
Requires either a borrowernumber or a categorycode key, but not both.
=cut | |||||
| 58 | ||||||
| 59 | sub GetMessagingPreferences { | |||||
| 60 | 0 | my $params = shift; | ||||
| 61 | ||||||
| 62 | 0 | return unless exists $params->{message_name}; | ||||
| 63 | 0 | return unless exists $params->{borrowernumber} xor exists $params->{categorycode}; # yes, xor | ||||
| 64 | 0 | my $sql = <<'END_SQL'; | ||||
| 65 | SELECT borrower_message_preferences.*, | |||||
| 66 | borrower_message_transport_preferences.message_transport_type, | |||||
| 67 | message_attributes.message_name, | |||||
| 68 | message_attributes.takes_days, | |||||
| 69 | message_transports.is_digest, | |||||
| 70 | message_transports.letter_module, | |||||
| 71 | message_transports.letter_code | |||||
| 72 | FROM borrower_message_preferences | |||||
| 73 | LEFT JOIN borrower_message_transport_preferences | |||||
| 74 | ON borrower_message_transport_preferences.borrower_message_preference_id = borrower_message_preferences.borrower_message_preference_id | |||||
| 75 | LEFT JOIN message_attributes | |||||
| 76 | ON message_attributes.message_attribute_id = borrower_message_preferences.message_attribute_id | |||||
| 77 | JOIN message_transports | |||||
| 78 | ON message_transports.message_attribute_id = message_attributes.message_attribute_id | |||||
| 79 | AND message_transports.message_transport_type = borrower_message_transport_preferences.message_transport_type | |||||
| 80 | WHERE message_attributes.message_name = ? | |||||
| 81 | END_SQL | |||||
| 82 | ||||||
| 83 | 0 | my @bind_params = ( $params->{'message_name'} ); | ||||
| 84 | 0 | if ( exists $params->{'borrowernumber'} ) { | ||||
| 85 | 0 | $sql .= " AND borrower_message_preferences.borrowernumber = ? "; | ||||
| 86 | 0 | push @bind_params, $params->{borrowernumber}; | ||||
| 87 | } else { | |||||
| 88 | 0 | $sql .= " AND borrower_message_preferences.categorycode = ? "; | ||||
| 89 | 0 | push @bind_params, $params->{categorycode}; | ||||
| 90 | } | |||||
| 91 | ||||||
| 92 | 0 | my $sth = C4::Context->dbh->prepare($sql); | ||||
| 93 | 0 | $sth->execute(@bind_params); | ||||
| 94 | 0 | my $return; | ||||
| 95 | 0 | my %transports; # helps build a list of unique message_transport_types | ||||
| 96 | 0 | ROW: while ( my $row = $sth->fetchrow_hashref() ) { | ||||
| 97 | 0 | next ROW unless $row->{'message_attribute_id'}; | ||||
| 98 | 0 | $return->{'days_in_advance'} = $row->{'days_in_advance'} if defined $row->{'days_in_advance'}; | ||||
| 99 | 0 | $return->{'wants_digest'} = $row->{'wants_digest'} if defined $row->{'wants_digest'}; | ||||
| 100 | 0 | $return->{'letter_code'} = $row->{'letter_code'}; | ||||
| 101 | 0 | $transports{$row->{'message_transport_type'}} = 1; | ||||
| 102 | } | |||||
| 103 | 0 0 | @{$return->{'transports'}} = keys %transports; | ||||
| 104 | 0 | return $return; | ||||
| 105 | } | |||||
| 106 | ||||||
| 107 - 122 | =head2 SetMessagingPreference
This method defines how a user (or a default for a patron category) wants to get a certain
message delivered. The list of valid message types can be delivered can be found in the
C<message_attributes> table, and the list of valid message transports can be
found in the C<message_transport_types> table.
C4::Members::Messaging::SetMessagingPreference( { borrowernumber => $borrower->{'borrowernumber'}
message_attribute_id => $message_attribute_id,
message_transport_types => [ qw( email sms ) ],
days_in_advance => 5
wants_digest => 1 } )
returns nothing useful.
=cut | |||||
| 123 | ||||||
| 124 | sub SetMessagingPreference { | |||||
| 125 | 0 | my $params = shift; | ||||
| 126 | ||||||
| 127 | 0 | unless (exists $params->{borrowernumber} xor exists $params->{categorycode}) { # yes, xor | ||||
| 128 | 0 | warn "SetMessagingPreference called without exactly one of borrowernumber or categorycode"; | ||||
| 129 | 0 | return; | ||||
| 130 | } | |||||
| 131 | 0 | foreach my $required ( qw( message_attribute_id message_transport_types ) ) { | ||||
| 132 | 0 | if ( ! exists $params->{ $required } ) { | ||||
| 133 | 0 | warn "SetMessagingPreference called without required parameter: $required"; | ||||
| 134 | 0 | return; | ||||
| 135 | } | |||||
| 136 | } | |||||
| 137 | 0 | $params->{'days_in_advance'} = undef unless exists ( $params->{'days_in_advance'} ); | ||||
| 138 | 0 | $params->{'wants_digest'} = 0 unless exists ( $params->{'wants_digest'} ); | ||||
| 139 | ||||||
| 140 | 0 | my $dbh = C4::Context->dbh(); | ||||
| 141 | ||||||
| 142 | 0 | my $delete_sql = <<'END_SQL'; | ||||
| 143 | DELETE FROM borrower_message_preferences | |||||
| 144 | WHERE message_attribute_id = ? | |||||
| 145 | END_SQL | |||||
| 146 | 0 | my @bind_params = ( $params->{'message_attribute_id'} ); | ||||
| 147 | 0 | if ( exists $params->{'borrowernumber'} ) { | ||||
| 148 | 0 | $delete_sql .= " AND borrowernumber = ? "; | ||||
| 149 | 0 | push @bind_params, $params->{borrowernumber}; | ||||
| 150 | } else { | |||||
| 151 | 0 | $delete_sql .= " AND categorycode = ? "; | ||||
| 152 | 0 | push @bind_params, $params->{categorycode}; | ||||
| 153 | } | |||||
| 154 | 0 | my $sth = $dbh->prepare( $delete_sql ); | ||||
| 155 | 0 | my $deleted = $sth->execute( @bind_params ); | ||||
| 156 | ||||||
| 157 | 0 | if ( $params->{'message_transport_types'} ) { | ||||
| 158 | 0 | my $insert_bmp = <<'END_SQL'; | ||||
| 159 | INSERT INTO borrower_message_preferences | |||||
| 160 | (borrower_message_preference_id, borrowernumber, categorycode, message_attribute_id, days_in_advance, wants_digest) | |||||
| 161 | VALUES | |||||
| 162 | (NULL, ?, ?, ?, ?, ?) | |||||
| 163 | END_SQL | |||||
| 164 | ||||||
| 165 | 0 | $sth = C4::Context->dbh()->prepare($insert_bmp); | ||||
| 166 | # set up so that we can easily construct the insert SQL | |||||
| 167 | 0 | $params->{'borrowernumber'} = undef unless exists ( $params->{'borrowernumber'} ); | ||||
| 168 | 0 | $params->{'categorycode'} = undef unless exists ( $params->{'categorycode'} ); | ||||
| 169 | 0 | my $success = $sth->execute( $params->{'borrowernumber'}, | ||||
| 170 | $params->{'categorycode'}, | |||||
| 171 | $params->{'message_attribute_id'}, | |||||
| 172 | $params->{'days_in_advance'}, | |||||
| 173 | $params->{'wants_digest'} ); | |||||
| 174 | # my $borrower_message_preference_id = $dbh->last_insert_id(); | |||||
| 175 | 0 | my $borrower_message_preference_id = $dbh->{'mysql_insertid'}; | ||||
| 176 | ||||||
| 177 | 0 | my $insert_bmtp = <<'END_SQL'; | ||||
| 178 | INSERT INTO borrower_message_transport_preferences | |||||
| 179 | (borrower_message_preference_id, message_transport_type) | |||||
| 180 | VALUES | |||||
| 181 | (?, ?) | |||||
| 182 | END_SQL | |||||
| 183 | 0 | $sth = C4::Context->dbh()->prepare($insert_bmtp); | ||||
| 184 | 0 0 | foreach my $transport ( @{$params->{'message_transport_types'}}) { | ||||
| 185 | 0 | my $success = $sth->execute( $borrower_message_preference_id, $transport ); | ||||
| 186 | } | |||||
| 187 | } | |||||
| 188 | 0 | return; | ||||
| 189 | } | |||||
| 190 | ||||||
| 191 - 197 | =head2 GetMessagingOptions my $messaging_options = C4::Members::Messaging::GetMessagingOptions() returns a hashref of messaging options available. =cut | |||||
| 198 | ||||||
| 199 | sub GetMessagingOptions { | |||||
| 200 | ||||||
| 201 | 0 | my $sql = <<'END_SQL'; | ||||
| 202 | select message_attributes.message_attribute_id, takes_days, message_name, message_transport_type, is_digest | |||||
| 203 | FROM message_attributes | |||||
| 204 | LEFT JOIN message_transports | |||||
| 205 | ON message_attributes.message_attribute_id = message_transports.message_attribute_id | |||||
| 206 | END_SQL | |||||
| 207 | ||||||
| 208 | 0 | my $sth = C4::Context->dbh->prepare($sql); | ||||
| 209 | 0 | $sth->execute(); | ||||
| 210 | 0 | my $choices; | ||||
| 211 | 0 | while ( my $row = $sth->fetchrow_hashref() ) { | ||||
| 212 | 0 | $choices->{ $row->{'message_name'} }->{'message_attribute_id'} = $row->{'message_attribute_id'}; | ||||
| 213 | 0 | $choices->{ $row->{'message_name'} }->{'message_name'} = $row->{'message_name'}; | ||||
| 214 | 0 | $choices->{ $row->{'message_name'} }->{'takes_days'} = $row->{'takes_days'}; | ||||
| 215 | 0 | $choices->{ $row->{'message_name'} }->{'has_digest'} = 1 if $row->{'is_digest'}; | ||||
| 216 | 0 | $choices->{ $row->{'message_name'} }->{'transport_' . $row->{'message_transport_type'}} = ' '; | ||||
| 217 | } | |||||
| 218 | ||||||
| 219 | 0 | my @return = values %$choices; | ||||
| 220 | # warn( Data::Dumper->Dump( [ \@return ], [ 'return' ] ) ); | |||||
| 221 | 0 | return \@return; | ||||
| 222 | } | |||||
| 223 | ||||||
| 224 - 233 | =head2 SetMessagingPreferencesFromDefaults
C4::Members::Messaging::SetMessagingPreferenceFromDefaults( { borrowernumber => $borrower->{'borrowernumber'}
categorycode => 'CPL' } );
Given a borrowernumber and a patron category code (from the C<borrowernumber> and C<categorycode> keys
in the parameter hashref), replace all of the patron's current messaging preferences with
whatever defaults are defined for the patron category.
=cut | |||||
| 234 | ||||||
| 235 | sub SetMessagingPreferencesFromDefaults { | |||||
| 236 | 0 | my $params = shift; | ||||
| 237 | ||||||
| 238 | 0 | foreach my $required ( qw( borrowernumber categorycode ) ) { | ||||
| 239 | 0 | unless ( exists $params->{ $required } ) { | ||||
| 240 | 0 | die "SetMessagingPreferencesFromDefaults called without required parameter: $required"; | ||||
| 241 | } | |||||
| 242 | } | |||||
| 243 | ||||||
| 244 | 0 | my $messaging_options = GetMessagingOptions(); | ||||
| 245 | 0 | OPTION: foreach my $option ( @$messaging_options ) { | ||||
| 246 | 0 | my $default_pref = GetMessagingPreferences( { categorycode => $params->{categorycode}, | ||||
| 247 | message_name => $option->{'message_name'} } ); | |||||
| 248 | # FIXME - except for setting the borrowernumber, it really ought to be possible | |||||
| 249 | # to have the output of GetMessagingPreferences be able to be the input | |||||
| 250 | # to SetMessagingPreference | |||||
| 251 | 0 | $default_pref->{message_attribute_id} = $option->{'message_attribute_id'}; | ||||
| 252 | 0 | $default_pref->{message_transport_types} = $default_pref->{transports}; | ||||
| 253 | 0 | $default_pref->{borrowernumber} = $params->{borrowernumber}; | ||||
| 254 | 0 | SetMessagingPreference( $default_pref ); | ||||
| 255 | } | |||||
| 256 | } | |||||
| 257 | ||||||
| 258 - 315 | =head1 TABLES =head2 message_queue The actual messages which will be sent via a cron job running F<misc/cronjobs/process_message_queue.pl>. =head2 message_attributes What kinds of messages can be sent? =head2 message_transport_types What transports can messages be sent vith? (email, sms, etc.) =head2 message_transports How are message_attributes and message_transport_types correlated? =head2 borrower_message_preferences What messages do the borrowers want to receive? =head2 borrower_message_transport_preferences What transport should a message be sent with? =head1 CONFIG =head2 Adding a New Kind of Message to the System =over 4 =item 1. Add a new template to the `letter` table. =item 2. Insert a row into the `message_attributes` table. =item 3. Insert rows into `message_transports` for each message_transport_type. =back =head1 SEE ALSO L<C4::Letters> =head1 AUTHOR Koha Development Team <http://koha-community.org/> Andrew Moore <andrew.moore@liblime.com> =cut | |||||
| 316 | ||||||
| 317 | 1; | |||||