From 8dcf2155443f280a2fecc95d3bd280545684309a Mon Sep 17 00:00:00 2001 From: Lari Taskula Date: Fri, 7 Apr 2017 09:55:29 +0000 Subject: [PATCH] Bug 14590: Validate messaging preferences Messaging preferences should be only available if a valid contact information is stored for the patron for that transport type. Otherwise, it should not be possible to select preferences for that transport type. For example, when attempting to set messages to be delivered via sms, we should automatically check patron's smsalertnumber before allowing this type of modification. If patron does not have a valid smsalertnumber and is not passing it along with the messaging preference change, we should not store those given messaging transport types. This patch implements exactly this. It uses Koha::Validation from Bug 14620 to validate contact informations and attaches it into patron modification logic - whenever messaging preferences are processed by Koha, preferences that link to an invalid or non-existent contact information will be removed. Client-side JavaScript checks are also implemented. When modifying patron information, messaging preferences for a certain transport type will be either enabled and/or disabled on the fly depending on validity of the contact info linked to that transport type (transport type "sms" => borrower "smsalertnumber"). TESTING: This feature requires tests both in OPAC and staff client. Requirements: 1. Apply patch(es) in Bug 14620 before this patch 2. Make sure EnhancedMessagingPreferences is enabled 3. Make sure EnhancedMessagingPreferencesOPAC is enabled 4. Make sure TalkingTechItivaPhoneNotification is enabled (activates transport type "phone") 5. Make sure SMSSendDriver is enabled (for simple testing purposes you can use the value "test") 6. Preference "ValidatePhoneNumber" needs a regular expression for validating phone numbers. An example regular expression is provided below the input field. You can use that while testing this feature. Copy-paste it into the input box and save preferences. (regex also provided below) ^((\+)?[1-9]{1,2})?([-\s\.])?((\(\d{1,4}\))|\d{1,4})(([-\s\.])?[0-9]{1,12}){1,2}$ TEST PLAN: 1. Login to staff client 2. Go to modification view of any patron 3. Scroll down all the way and you should see "Patron messaging preferences" table including checkboxes for transport types "SMS", "Phone" and "Email". 4. If the patron you are modifying has any contact information of the following "Primary email", "Primary phone", "SMS number", please clear those fields. 5. Scroll down. All checkboxes for the given transport types should now be disabled. 6. Modify field "Primary email" and insert "test". A warning of invalid email should appear. 7. Scroll down. Checkboxes for transport type "Email" should still be disabled. 8. Modify field "Primary email" and insert "nobody@example.com". 9. Scroll down. Checkboxes for transport type "Email" should now be enabled. 10. Select email as transport type for each message type and click "Save". 11. Go back to modification screen. The messaging preferences should still appear as you stored them. 12. Repeat steps 6-11 also for both "Phone" and "SMS number". When inserting text into phone number fields, they should appear as invalid, so test like that. 13. After successful testing, test also other patron modification screens. Go to patron's Details tab and you should see multiple "Edit" links on that page. The point is to make sure transport type selections are correctly removed from the patron if the modification screen lets you modify for example primary email, but does not present the messaging preferences at the bottom of the page. So, as an example, first insert patron a valid email and select all email transport types. Then, go to the "Edit" link right above "Patron messaging preferences" title on patron's details page. This page lets you modify "Primary email" but not messaging preferences. Clear the "Primary email" field and save, and observe that all previously selected email transport types are now removed. 14. Give your patron a valid email and go to Details tab -> "Edit" link below "Patron messaging preferences title" on the left. You should still be able to select email as transport types. 15. Go remove patron's primary email and repeat step 14. You will observe that it is no longer possible to select email as a transport type. 16. Try steps 13-15 with other transport types as well After this test plan you should have a pretty good idea of the feature. As mentioned earlier, this feature requires tests on the OPAC side as well. So attempt this also via OPAC and make sure preferences are validated when the librarian approves patron's modifications. --- C4/Form/MessagingPreferences.pm | 64 +++++++++- C4/Members.pm | 16 +++ C4/Members/Messaging.pm | 138 ++++++++++++++++++++- Koha/Patron/Modification.pm | 17 +++ Koha/Validation.pm | 4 + .../prog/en/modules/members/memberentrygen.tt | 10 ++ koha-tmpl/intranet-tmpl/prog/js/members.js | 12 ++ .../intranet-tmpl/prog/js/messaging-preference.js | 93 ++++++++++++++ .../bootstrap/en/modules/opac-messaging.tt | 22 +++- .../opac-tmpl/bootstrap/js/messaging-preference.js | 94 ++++++++++++++ members/memberentry.pl | 4 +- opac/opac-messaging.pl | 2 +- 12 files changed, 467 insertions(+), 9 deletions(-) create mode 100644 koha-tmpl/intranet-tmpl/prog/js/messaging-preference.js create mode 100644 koha-tmpl/opac-tmpl/bootstrap/js/messaging-preference.js diff --git a/C4/Form/MessagingPreferences.pm b/C4/Form/MessagingPreferences.pm index b98015f..3ec41e9 100644 --- a/C4/Form/MessagingPreferences.pm +++ b/C4/Form/MessagingPreferences.pm @@ -77,11 +77,47 @@ sub handle_form_action { # TODO: If a "NONE" box and another are checked somehow (javascript failed), we should pay attention to the "NONE" box my $prefs_set = 0; OPTION: foreach my $option ( @$messaging_options ) { - my $updater = { %{ $target_params }, - message_attribute_id => $option->{'message_attribute_id'} }; - + my $updater = { + message_attribute_id => $option->{'message_attribute_id'} + }; + + $updater->{borrowernumber} = $target_params->{borrowernumber}; + if ($target_params->{categorycode} && !$target_params->{borrowernumber}) { + $updater->{categorycode} = $target_params->{categorycode}; + delete $updater->{borrowernumber}; + } + # find the desired transports - @{$updater->{'message_transport_types'}} = $query->multi_param( $option->{'message_attribute_id'} ); + @{$updater->{'message_transport_types'}} = + $query->multi_param( $option->{'message_attribute_id'} ); + + my $email = $query->param('email'); + my $phone = $query->param('phone'); + my $smsnumber = $query->param('SMSnumber'); + + # Messaging preference validation. Make sure there is a valid contact + # information provided for every transport method. Otherwise remove + # the transport method, because the message cannot be delivered! + if (_no_contact_set($email, $target_params, 'email')) { + my $id = _transport_set( + 'email', @{$updater->{'message_transport_types'}} + ); + splice(@{$updater->{'message_transport_types'}}, $id, 1) if $id > -1; + } + if (_no_contact_set($phone, $target_params, 'phone')) { + my $id = _transport_set( + 'phone',@{$updater->{'message_transport_types'}} + ); + splice(@{$updater->{'message_transport_types'}}, $id, 1) if $id > -1; + } + if (_no_contact_set($smsnumber, $target_params, 'smsalertnumber')) { + my $id = _transport_set( + 'sms', + @{$updater->{'message_transport_types'}} + ); + splice(@{$updater->{'message_transport_types'}}, $id, 1) if $id > -1; + } + next OPTION unless $updater->{'message_transport_types'}; if ( $option->{'has_digest'} ) { @@ -149,6 +185,26 @@ sub set_form_values { $template->param(messaging_preferences => $messaging_options); } +sub _no_contact_set { + my ($param, $target_params, $target_param_name) = @_; + + if (defined $param && !$param) { + return 1; + } + elsif (!defined $param && exists $target_params->{$target_param_name} + && !$target_params->{$target_param_name}) { + return 1; + } else { + return 0; + } +} + +sub _transport_set { + my ($name, @transport_methods) = @_; + + return List::MoreUtils::firstidx { $_ eq $name } @transport_methods; +} + =head1 TODO =over 4 diff --git a/C4/Members.pm b/C4/Members.pm index ee10cc7..87d2f45 100644 --- a/C4/Members.pm +++ b/C4/Members.pm @@ -396,6 +396,22 @@ sub ModMember { } } + # Validate messaging preferences if any of the following field have + # been removed + if (!$data{email} || !$data{phone} || !$data{smsalertnumber}) { + C4::Members::Messaging::DeleteAllMisconfiguredPreferences( + $data{borrowernumber} + ); + } + # ...or if any of the given contact information is invalid + elsif ($data{email} && !Koha::Validation::email($data{email}) || + $data{phone} && !Koha::Validation::phone($data{phone}) || + $data{smsalertnumber} && !Koha::Validation::phone($data{phone})) { + C4::Members::Messaging::DeleteAllMisconfiguredPreferences( + $data{borrowernumber} + ); + } + # If NorwegianPatronDBEnable is enabled, we set syncstatus to something that a # cronjob will use for syncing with NL if ( C4::Context->preference('NorwegianPatronDBEnable') && C4::Context->preference('NorwegianPatronDBEnable') == 1 ) { diff --git a/C4/Members/Messaging.pm b/C4/Members/Messaging.pm index 2270c37..ef5c274 100644 --- a/C4/Members/Messaging.pm +++ b/C4/Members/Messaging.pm @@ -21,7 +21,7 @@ use strict; use warnings; use C4::Context; - +use Koha::Validation; =head1 NAME @@ -253,6 +253,142 @@ sub SetMessagingPreferencesFromDefaults { $default_pref->{borrowernumber} = $params->{borrowernumber}; SetMessagingPreference( $default_pref ); } + # Finally, delete all misconfigured preferences + DeleteAllMisconfiguredPreferences($params->{borrowernumber}); +} + +=head2 DeleteAllMisconfiguredPreferences + + C4::Members::Messaging::DeleteAllMisconfiguredPreferences( [ $borrowernumber ] ); + +Deletes all misconfigured preferences for ALL borrowers that have invalid contact information for +the transport types. Given a borrowernumber, deletes misconfigured preferences only for this borrower. + +return: returns array of arrayrefs to the deleted preferences (borrower_message_preference_id and message_transport_type) + +=cut + +sub DeleteAllMisconfiguredPreferences { + my $borrowernumber = shift; + + my @deleted_prefs; + + push(@deleted_prefs, DeleteMisconfiguredPreference("email", "email", "email", + $borrowernumber)); + push(@deleted_prefs, DeleteMisconfiguredPreference("phone", "phone", "phone", + $borrowernumber)); + push(@deleted_prefs, DeleteMisconfiguredPreference("sms", "smsalertnumber", + "phone", $borrowernumber)); + + return @deleted_prefs; +} + +=head2 DeleteMisconfiguredPreference + + C4::Members::Messaging::DeleteMisconfiguredPreference( + $type, $contact, $validator [, $borrowernumber ] + ); + +Takes a messaging preference type and the primary contact method for it, and +a string to define the Koha::Validation that should be used to determine whether +the preference is misconfigured. + +A messaging preference is misconfigured when it is linked with invalid contact +information. E.g. messaging type email expects the user to have a valid e-mail +address in order to work. + +Deletes misconfigured preferences for ALL borrowers that have invalid contact +information for that transport type. Given a borrowernumber, deletes misconfigured +preferences only for this borrower. + +return: returns array of arrayrefs to the deleted preferences +(borrower_message_preference_id and message_transport_type) + +=cut + +sub DeleteMisconfiguredPreference { + my ($type, $contact, $validator, $borrowernumber) = @_; + + if (not defined $type or not defined $contact or not defined $validator) { + return 0; + } + + my @misconfigured_prefs; + + # Get all messaging preferences and borrower's contact information + my $dbh = C4::Context->dbh(); + my $query = " + + SELECT + borrower_message_preferences.borrower_message_preference_id, + borrower_message_transport_preferences.message_transport_type, + borrowers.$contact + + FROM + borrower_message_preferences, + borrower_message_transport_preferences, + borrowers + + WHERE + borrower_message_preferences.borrower_message_preference_id + = + borrower_message_transport_preferences.borrower_message_preference_id + + AND + borrowers.borrowernumber = borrower_message_preferences.borrowernumber + + AND + borrower_message_transport_preferences.message_transport_type = ? + "; + + $query .= " AND borrowers.borrowernumber = ?" if defined $borrowernumber; + + my $sth = $dbh->prepare($query); + + if (defined $borrowernumber){ + $sth->execute($type, $borrowernumber); + } else { + $sth->execute($type); + } + + while (my $ref = $sth->fetchrow_arrayref) { + if ($$ref[1] eq $type) { + if (not defined $$ref[2] or defined $$ref[2] and $$ref[2] eq "") { + my $valid_contact = 0; # delete prefs if empty contact + unless ($valid_contact && $$ref[2]) { + # push the misconfigured preferences into an array + push(@misconfigured_prefs, $$ref[0]); + } + } + else { + my ($valid_contact, $err, $err_msg) = + Koha::Validation->$validator($$ref[2]); + unless ($valid_contact && $$ref[2]) { + # push the misconfigured preferences into an array + push(@misconfigured_prefs, $$ref[0]); + } + } + } + } + + $sth = $dbh->prepare(" + + DELETE FROM + borrower_message_transport_preferences + + WHERE + borrower_message_preference_id = ? AND message_transport_type = ? + "); + + my @deleted_prefs; + foreach my $id (@misconfigured_prefs){ + # delete the misconfigured pref + $sth->execute($id, $type); + # push it into array that we will return + push (@deleted_prefs, [$id,$type]); + } + + return @deleted_prefs; } =head1 TABLES diff --git a/Koha/Patron/Modification.pm b/Koha/Patron/Modification.pm index 78f092d..fabebad 100644 --- a/Koha/Patron/Modification.pm +++ b/Koha/Patron/Modification.pm @@ -140,6 +140,23 @@ sub approve { && $attr->{value} == 0 ); } + + # Validate messaging preferences if any of the following field + # have been removed + if (!$data->{email} || !$data->{phone} || + !$data->{smsalertnumber}) { + C4::Members::Messaging::DeleteAllMisconfiguredPreferences( + $self->borrowernumber + ); + } + # ...or if any of the given contact information is invalid + elsif (!Koha::Validation::email($data->{email}) || + !Koha::Validation::phone($data->{phone}) || + !Koha::Validation::phone($data->{phone})) { + C4::Members::Messaging::DeleteAllMisconfiguredPreferences( + $self->borrowernumber + ); + } } catch { if ( $_->isa('DBIx::Class::Exception') ) { diff --git a/Koha/Validation.pm b/Koha/Validation.pm index 94006d8..69b84e0 100644 --- a/Koha/Validation.pm +++ b/Koha/Validation.pm @@ -39,6 +39,7 @@ This module lets you validate given inputs. =head3 email Koha::Validation::email("email@address.com"); +Koha::Validation->email("email@address.com"); Validates given email. @@ -48,6 +49,7 @@ returns: 1 if the given email is valid (or empty), 0 otherwise. sub email { my $address = shift; + $address = shift if $address eq __PACKAGE__; return 1 unless $address; return 0 if $address =~ /(^(\s))|((\s)$)/; @@ -58,6 +60,7 @@ sub email { =head3 phone Koha::Validation::validate_phonenumber(123456789); +Koha::Validation->validate_phonenumber(123456789); Validates given phone number. @@ -67,6 +70,7 @@ returns: 1 if the given phone number is valid (or empty), 0 otherwise. sub phone { my $phonenumber = shift; + $phonenumber = shift if $phonenumber eq __PACKAGE__; return 1 unless $phonenumber; return 0 if $phonenumber =~ /(^(\s))|((\s)$)/; diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt index b71ff60..e7b3e8f 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt @@ -64,6 +64,15 @@ $(document).ready(function() { $(".toggler").toggle(); }); + [% IF email %] + patron_email = "[% email %]"; + [% END %] + [% IF phone %] + patron_phone = "[% phone %]"; + [% END %] + [% IF smsalertnumber %] + patron_sms = "[% smsalertnumber %]"; + [% END %] var MSG_INCORRECT_PHONE = _("Please enter a valid phone number."); $.validator.addMethod('phone', function(value) { @@ -114,6 +123,7 @@ $(document).ready(function() { //]]> + [% INCLUDE 'header.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/js/members.js b/koha-tmpl/intranet-tmpl/prog/js/members.js index d1ded81..6dfe6c34 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/members.js +++ b/koha-tmpl/intranet-tmpl/prog/js/members.js @@ -372,6 +372,18 @@ $(document).ready(function(){ $("#phone, #phonepro, #B_phone, #SMSnumber").each(function(){ $(this).val($.trim($(this).val())); }); + disableCheckboxesWithInvalidPreferences($("#email"), "email"); + disableCheckboxesWithInvalidPreferences($("#phone"), "phone"); + disableCheckboxesWithInvalidPreferences($("#SMSnumber"), "sms"); + $("#email").on("input change", function() { + disableCheckboxesWithInvalidPreferences($("#email"), "email"); + }); + $("#phone").on("input change", function() { + disableCheckboxesWithInvalidPreferences($("#phone"), "phone"); + }); + $("#SMSnumber").on("input change", function() { + disableCheckboxesWithInvalidPreferences($("#SMSnumber"), "sms"); + }); var mrform = $("#manual_restriction_form"); var mrlink = $("#add_manual_restriction"); diff --git a/koha-tmpl/intranet-tmpl/prog/js/messaging-preference.js b/koha-tmpl/intranet-tmpl/prog/js/messaging-preference.js new file mode 100644 index 0000000..8da5431 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/js/messaging-preference.js @@ -0,0 +1,93 @@ +/** + * + * Used in: koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt + * + * This component is also used in OPAC: koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-messaging.tt + * For modifications, edit also OPAC version in: koha-tmpl/opac-tmpl/bootstrap/en/js/messaging-preference.js + * + * Disables and clears checkboxes from messaging preferences + * if there is either invalid or nonexistent contact information + * for the message transfer type. + * + * @param {HTMLInputElement} elem + * The contact field + * @param {string} id_attr + * Checkboxes' id attribute so that we can recognize them + */ +// Settings for messaging-preference.js +var patron_messaging_checkbox_preferences = { + email: { + checked_checkboxes: null, + is_enabled: true, + disabled_checkboxes: null + }, + sms: { + checked_checkboxes: null, + is_enabled: true, + disabled_checkboxes: null + }, + phone: { + checked_checkboxes: null, + is_enabled: true, + disabled_checkboxes: null + } +}; + +function disableCheckboxesWithInvalidPreferences(elem, id_attr) { + if (!$(elem).length && typeof window["patron_" + id_attr] !== "undefined") { + return; + } + // Get checkbox preferences for the element + var checkbox_prefs = eval("patron_messaging_checkbox_preferences." + id_attr); + // Check if element is empty or not valid + if (!$(elem).length || $(elem).val().length == 0 || !$(elem).valid()) { + + if (checkbox_prefs.is_enabled) { + // Save the state of checked checkboxes + checkbox_prefs.checked_checkboxes = $("input[type='checkbox'][id^=" + id_attr + "][value=" + id_attr + "]:checked"); + + // Save the state of automatically disabled checkboxes + // (We don't want to enable them once the e-mail is valid!) + checkbox_prefs.disabled_checkboxes = $("input[type='checkbox'][id^=" + id_attr + "][value=" + id_attr + "]:disabled"); + + // Clear patron messaging preferences checkboxes + $("input[type='checkbox'][id^=" + id_attr + "][value=" + id_attr + "]").removeAttr("checked"); + + // Then disable checkboxes from patron messaging perferences + $("input[type='checkbox'][id^=" + id_attr + "][value=" + id_attr + "]").attr("disabled", "disabled"); + + // Color table cell's background emphasize the disabled state of the checkbox + $("input[type='checkbox'][id^=" + id_attr + "][value=" + id_attr + "]").parent().css("background-color", "#E8F0F8"); + + // Show notice about missing contact in messaging preferences box + $("#required-" + id_attr).css("display", "block"); + + checkbox_prefs.is_enabled = false; + } + } else { + + if (!checkbox_prefs.is_enabled) { + // Enable patron messaging preferences checkboxes + $("input[type='checkbox'][id^=" + id_attr + "][value=" + id_attr + "]").removeAttr("disabled"); + + // Disable the checkboxes that were disabled by default + checkbox_prefs.disabled_checkboxes.each(function() { + $(this).attr("disabled", "disabled"); + $(this).removeAttr("checked"); + }); + + // Restore the state of checkboxes + checkbox_prefs.checked_checkboxes.each(function() { + $(this).attr("checked", "checked"); + }); + + // Remove the background color from table cell + $("input[type='checkbox'][id^=" + id_attr + "][value=" + id_attr + "]").parent().css("background-color", "#FFF"); + + // Remove notice about missing contact from messaging preferences box + $("#required-" + id_attr).css("display", "none"); + + checkbox_prefs.is_enabled = true; + } + } +} diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-messaging.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-messaging.tt index 832672f..e19168e 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-messaging.tt +++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-messaging.tt @@ -25,6 +25,9 @@ [% IF Koha.Preference( 'EnhancedMessagingPreferencesOPAC' ) %]

Your messaging settings

+

Primary email

is required in order to set Email preferences.
+ [% IF ( TalkingTechItivaPhone AND ValidatePhoneNumber ) %]

Primary phone

is required in order to set Phone preferences.
[% END %] + [% IF ( SMSSendDriver AND ValidatePhoneNumber ) %]

SMS number

is required in order to set SMS preferences.
[% END %] [% IF ( settings_updated ) %]

Settings updated

[% END %] @@ -214,11 +217,28 @@ error.width("auto"); } }); - $("#SMSnumber").on("change", function(){ + [% IF BORROWER_INFO.email %] + patron_email = "[% BORROWER_INFO.email %]"; + [% END %] + [% IF BORROWER_INFO.phone %] + patron_phone = "[% BORROWER_INFO.phone %]"; + [% END %] + [% IF smsalertnumber %] + patron_sms = "[% BORROWER_INFO.smsalertnumber %]"; + [% END %] + disableCheckboxesWithInvalidPreferences(undefined, "email"); + disableCheckboxesWithInvalidPreferences(undefined, "phone"); + [% IF SMSSendDriver %] + $("#SMSnumber").on("input change", function(){ $(this).val($.trim($(this).val())); + [% IF ( ValidatePhoneNumber ) %] + disableCheckboxesWithInvalidPreferences($("#SMSnumber"), "sms"); + [% END %] }); + [% END %] }); //]]> + [% END %] diff --git a/koha-tmpl/opac-tmpl/bootstrap/js/messaging-preference.js b/koha-tmpl/opac-tmpl/bootstrap/js/messaging-preference.js new file mode 100644 index 0000000..f638ca5 --- /dev/null +++ b/koha-tmpl/opac-tmpl/bootstrap/js/messaging-preference.js @@ -0,0 +1,94 @@ +/** + * + * Used in: koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-messaging.tt + * + * This component is also used in Staff client: koha-tmpl/intranet-tmpl/prog/en/modules/memberentrygen.tt + * For modifications, edit also Staff client version in: koha-tmpl/intranet-tmpl/prog/en/js/messaging-preference.js + * + * Disables and clears checkboxes from messaging preferences + * if there is either invalid or nonexistent contact information + * for the message transfer type. + * + * @param {HTMLInputElement} elem + * The contact field + * @param {string} id_attr + * Checkboxes' id attribute so that we can recognize them + */ +// Settings for messaging-preference.js +var patron_messaging_checkbox_preferences = { + email: { + checked_checkboxes: null, + is_enabled: true, + disabled_checkboxes: null + }, + sms: { + checked_checkboxes: null, + is_enabled: true, + disabled_checkboxes: null + }, + phone: { + checked_checkboxes: null, + is_enabled: true, + disabled_checkboxes: null + } +}; + +function disableCheckboxesWithInvalidPreferences(elem, id_attr) { + if (!$(elem).length && typeof window["patron_" + id_attr] !== "undefined") { + return; + } + // Get checkbox preferences for the element + var checkbox_prefs = eval("patron_messaging_checkbox_preferences." + id_attr); + // Check if element is empty or not valid + + if (!$(elem).length || $(elem).val().length == 0 || !$(elem).valid()) { + + if (checkbox_prefs.is_enabled) { + // Save the state of checked checkboxes + checkbox_prefs.checked_checkboxes = $("input[type='checkbox'][id^=" + id_attr + "][value=" + id_attr + "]:checked"); + + // Save the state of automatically disabled checkboxes + // (We don't want to enable them once the e-mail is valid!) + checkbox_prefs.disabled_checkboxes = $("input[type='checkbox'][id^=" + id_attr + "][value=" + id_attr + "]:disabled"); + + // Clear patron messaging preferences checkboxes + $("input[type='checkbox'][id^=" + id_attr + "][value=" + id_attr + "]").removeAttr("checked"); + + // Then disable checkboxes from patron messaging perferences + $("input[type='checkbox'][id^=" + id_attr + "][value=" + id_attr + "]").attr("disabled", "disabled"); + + // Color table cell's background emphasize the disabled state of the checkbox + $("input[type='checkbox'][id^=" + id_attr + "][value=" + id_attr + "]").parent().css("background-color", "#E8F0F8"); + + // Show notice about missing contact in messaging preferences box + $("#required-" + id_attr).css("display", "block"); + + checkbox_prefs.is_enabled = false; + } + } else { + + if (!checkbox_prefs.is_enabled) { + // Enable patron messaging preferences checkboxes + $("input[type='checkbox'][id^=" + id_attr + "][value=" + id_attr + "]").removeAttr("disabled"); + + // Disable the checkboxes that were disabled by default + checkbox_prefs.disabled_checkboxes.each(function() { + $(this).attr("disabled", "disabled"); + $(this).removeAttr("checked"); + }); + + // Restore the state of checkboxes + checkbox_prefs.checked_checkboxes.each(function() { + $(this).attr("checked", "checked"); + }); + + // Remove the background color from table cell + $("input[type='checkbox'][id^=" + id_attr + "][value=" + id_attr + "]").parent().css("background-color", "#FFF"); + + // Remove notice about missing contact from messaging preferences box + $("#required-" + id_attr).css("display", "none"); + + checkbox_prefs.is_enabled = true; + } + } +} diff --git a/members/memberentry.pl b/members/memberentry.pl index 970e478..51daa4a 100755 --- a/members/memberentry.pl +++ b/members/memberentry.pl @@ -438,7 +438,7 @@ if ((!$nok) and $nodouble and ($op eq 'insert' or $op eq 'save')){ C4::Members::Attributes::SetBorrowerAttributes($borrowernumber, $extended_patron_attributes); } if (C4::Context->preference('EnhancedMessagingPreferences') and $input->param('setting_messaging_prefs')) { - C4::Form::MessagingPreferences::handle_form_action($input, { borrowernumber => $borrowernumber }, $template, 1, $newdata{'categorycode'}); + C4::Form::MessagingPreferences::handle_form_action($input, \%newdata, $template, 1, $newdata{'categorycode'}); } # Try to do the live sync with the Norwegian national patron database, if it is enabled if ( exists $data{'borrowernumber'} && C4::Context->preference('NorwegianPatronDBEnable') && C4::Context->preference('NorwegianPatronDBEnable') == 1 ) { @@ -499,7 +499,7 @@ if ((!$nok) and $nodouble and ($op eq 'insert' or $op eq 'save')){ C4::Members::Attributes::SetBorrowerAttributes($borrowernumber, $extended_patron_attributes); } if (C4::Context->preference('EnhancedMessagingPreferences') and $input->param('setting_messaging_prefs')) { - C4::Form::MessagingPreferences::handle_form_action($input, { borrowernumber => $borrowernumber }, $template); + C4::Form::MessagingPreferences::handle_form_action($input, \%data, $template); } } print scalar ($destination eq "circ") ? diff --git a/opac/opac-messaging.pl b/opac/opac-messaging.pl index eb7c8eb..1646839 100755 --- a/opac/opac-messaging.pl +++ b/opac/opac-messaging.pl @@ -77,7 +77,7 @@ if ( defined $query->param('modify') && $query->param('modify') eq 'yes' ) { $borrower = C4::Members::GetMember( borrowernumber => $borrowernumber ); } - C4::Form::MessagingPreferences::handle_form_action($query, { borrowernumber => $borrowernumber }, $template); + C4::Form::MessagingPreferences::handle_form_action($query, $borrower, $template); } C4::Form::MessagingPreferences::set_form_values({ borrowernumber => $borrower->{'borrowernumber'} }, $template); -- 2.7.4