diff --git a/Koha/AdditionalContents.pm b/Koha/AdditionalContents.pm index 3ed9f42f41..430ff53934 100644 --- a/Koha/AdditionalContents.pm +++ b/Koha/AdditionalContents.pm @@ -63,6 +63,8 @@ location is one of this: - OpacLoginInstructions - OpacSuggestionInstructions - ArticleRequestsDisclaimerText +- CookieConsentBar +- CookieConsentPopup =cut diff --git a/Koha/Template/Plugin/JSConsents.pm b/Koha/Template/Plugin/JSConsents.pm new file mode 100644 index 0000000000..174a36a02e --- /dev/null +++ b/Koha/Template/Plugin/JSConsents.pm @@ -0,0 +1,69 @@ +package Koha::Template::Plugin::JSConsents; + +# Copyright 2021 PTFS Europe +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Template::Plugin; +use base qw( Template::Plugin ); +use MIME::Base64 qw{ decode_base64 }; +use JSON qw{ decode_json }; +use Encode qw{ encode_utf8 }; + +use C4::Context; + +sub all { + my ( $self, $filter ) = @_; + + my $consents = C4::Context->preference('CookieConsentedJS'); + if ( length $consents > 0 ) { + my $decoded_consents = decode_base64($consents); + my $convert_to_utf8 = encode_utf8($decoded_consents); + my $consents_array = decode_json $convert_to_utf8; + my @filtered_consents = grep { $_->{$filter} } @{$consents_array}; + return \@filtered_consents; + } else { + return []; + } +} + +1; + +=head1 NAME + +Koha::Template::Plugin::JSConsents - TT Plugin for Javascript consents +Provided by CookieConsentedJS syspref + +=head1 SYNOPSIS + +[% USE JSConsents %] + +[% JSConsents.all() %] + +=head1 ROUTINES + +=head2 all + +In a template, you can get the all Javascript snippets +that require consent using the following TT: +[% JSConsents.all() %] +The consents are returned in an array of hashes + +=head1 AUTHOR + +Andrew Isherwood + +=cut diff --git a/admin/preferences.pl b/admin/preferences.pl index 45a5891c62..73b8c442e3 100755 --- a/admin/preferences.pl +++ b/admin/preferences.pl @@ -59,12 +59,17 @@ sub _get_chunk { if( $options{'syntax'} ){ $chunk->{'syntax'} = $options{'syntax'}; } - - if( $options{'type'} && $options{'type'} eq 'modalselect' ){ - $chunk->{'source'} = $options{'source'}; - $chunk->{'exclusions'} = $options{'exclusions'} // ""; - $chunk->{'required'} = $options{'required'} // ""; - $chunk->{'type'} = 'modalselect'; + if( $options{'type'} ) { + if( $options{'type'} eq 'modalselect' ){ + $chunk->{'source'} = $options{'source'}; + $chunk->{'exclusions'} = $options{'exclusions'} // ""; + $chunk->{'required'} = $options{'required'} // ""; + $chunk->{'type'} = 'modalselect'; + } elsif( $options{'type'} eq 'modaljs' ){ + $chunk->{'type'} = 'modaljs'; + $chunk->{'initiator'} = $options{'initiator'}; + $chunk->{'processor'} = $options{'processor'}; + } } if ( $options{'class'} && $options{'class'} eq 'password' ) { diff --git a/installer/data/mysql/atomicupdate/bug_27378-add_cookie_consents.pl b/installer/data/mysql/atomicupdate/bug_27378-add_cookie_consents.pl new file mode 100644 index 0000000000..40f2904985 --- /dev/null +++ b/installer/data/mysql/atomicupdate/bug_27378-add_cookie_consents.pl @@ -0,0 +1,20 @@ +use Modern::Perl; + +return { + bug_number => "27378", + description => "Adds the sysprefs for cookie consents", + up => sub { + my ($args) = @_; + my ( $dbh, $out ) = @$args{qw(dbh out)}; + + $dbh->do( + q| INSERT IGNORE INTO systempreferences (variable, value, explanation, options, type) VALUES ('CookieConsentedJS', '', 'Add Javascript code that will run if cookie consent is provided (e.g. tracking code).', '', 'Free'); | + ); + say $out "Added new system preference 'CookieConsentedJS'"; + + $dbh->do( + q| INSERT IGNORE INTO systempreferences (variable, value, explanation, options, type) VALUES ('CookieConsent', '0', 'Require cookie consent to be displayed', '', 'YesNo'); | + ); + say $out "Added new system preference 'CookieConsent'"; + }, +}; diff --git a/installer/data/mysql/mandatory/sysprefs.sql b/installer/data/mysql/mandatory/sysprefs.sql index aa8a526e38..fad32d896e 100644 --- a/installer/data/mysql/mandatory/sysprefs.sql +++ b/installer/data/mysql/mandatory/sysprefs.sql @@ -158,6 +158,8 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` ('ConfirmFutureHolds','0','','Number of days for confirming future holds','Integer'), ('ConsiderOnSiteCheckoutsAsNormalCheckouts','1',NULL,'Consider on-site checkouts as normal checkouts','YesNo'), ('ContentWarningField', '', NULL, 'MARC field to use for content warnings', 'Free'), +('CookieConsent', '0', NULL, 'Require cookie consent to be displayed', 'YesNo'), +('CookieConsentedJS', '', NULL, 'Add Javascript code that will run if cookie consent is provided (e.g. tracking code).', 'Free'), ('CreateAVFromCataloguing', '1', '', 'Ability to create authorized values from the cataloguing module', 'YesNo'), ('CronjobLog','0',NULL,'If ON, log information from cron jobs.','YesNo'), ('CumulativeRestrictionPeriods',0,NULL,'Cumulate the restriction periods instead of keeping the highest','YesNo'), diff --git a/koha-tmpl/intranet-tmpl/prog/css/preferences.css b/koha-tmpl/intranet-tmpl/prog/css/preferences.css index ce15265389..d0f41db136 100644 --- a/koha-tmpl/intranet-tmpl/prog/css/preferences.css +++ b/koha-tmpl/intranet-tmpl/prog/css/preferences.css @@ -3,7 +3,8 @@ .preference-multi, .preference-long, .preference-file, -.preference-modalselect { +.preference-modalselect, +.preference-modaljs { width: 20em; } @@ -15,11 +16,13 @@ width: 5em; } -input[type="text"].modalselect { +input[type="text"].modalselect, +input[type="text"].modaljs { cursor: pointer; } -input[type="text"].modalselect:hover { +input[type="text"].modalselect:hover, +input[type="text"].modaljs:hover { background-color: #FFC; } diff --git a/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss b/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss index e25e4a5460..6a8f64e29e 100644 --- a/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss +++ b/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss @@ -2952,6 +2952,17 @@ button, } } + &.btn-info { + color: #fff; + background-color: #194EA3; + border-color: #0B439D; + } + + &.btn-success { + background-color: #419641; + border-color: #398339; + } + &.btn-danger { background-color: #CC3333; border-color: #9B2323; @@ -4302,6 +4313,86 @@ div .suggestion_note { } } +#cookieConsentedJSItems { + #cookieConsentedJSWarning { + margin: 20px 0; + text-align: center; + font-weight: 800; + font-size: 120%; + } + .cookieConsentedJSItem { + margin-bottom: 30px; + padding: 10px; + border: 1px solid #ccc; + } + .consentRow { + display: flex; + margin-bottom: 20px; + .consentItem { + margin-right: 40px; + } + .consentItem:last-child { + margin-right: 0; + } + } + .codeRow { + display: block; + } + .consentDelete { + display: block; + text-align: right; + } +} + +/* Cookie consent bar */ +#cookieConsentBar { + display: none; + padding: 20px; + position: fixed; + bottom: 0; + left: 0; + right: 0; + background: rgba(0,0,0,0.7); + color: rgba(255,255,255,0.9); + z-index: 1; + a:link, a:visited { + color: #d7ebff; + } + #consentButtons { + margin-top: 10px; + text-align: right; + } + button:not(:last-child) { + margin-right: 10px; + } +} + +/* Cookie consent modal */ +#cookieConsentModal { + .modal-dialog { + width: 700px; + } + .consentModalItem { + display: flex; + align-items: center; + border: 1px solid #ccc; + padding: 10px 20px; + border-radius: 5px; + } + .consentModalItem:not(:last-child) { + margin-bottom: 20px; + } + .consentItemCheckbox { + padding-right: 20px; + } + .consentItemName { + font-weight: bold; + } + #cookieConsentPopupText { + margin: 20px 0; + } +} + @import "header"; @import "toolbar"; @import "forms"; diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/header.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/header.inc index e4c6280285..0ab7ddbfdc 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/header.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/header.inc @@ -3,6 +3,9 @@ [% USE Desks %] [% USE Registers %] [% USE Koha %] +[% IF Koha.Preference( 'CookieConsent' ) %] + [% USE JSConsents %] +[% END %]