From 24d4a4c74c41a885e9f59b3d3dd4ff3a86c4b268 Mon Sep 17 00:00:00 2001 From: Aleisha Amohia Date: Thu, 12 Jan 2017 22:54:00 +0000 Subject: [PATCH] [SIGNED-OFF] Bug 4461: Add a context-sensitive 'Report a Problem' feature to OPAC This patch adds a 'Report a problem' link to the bottom of every page in the OPAC. The user can choose to submit their report to the library or Koha administrator. The report will store the user's problem message, but also their username and the page they were on when they clicked the 'report a problem' link. The patch adds a table 'problem_reports' to the db. Update: This patch adds a check for the KohaAdminEmailAddress and library branch email before sending the report. Update: Fix merge conflicts To test: 1) Apply patch, update database, rebuild schema 2) Restart koha-common and memcached 3) Confirm that your user has an email address. 4) Confirm that your library does NOT have an email address. 5) Confirm that your syspref KohaAdminEmailAddress is NOT filled. 6) Log into OPAC 7) Click the 'Report a problem' link at the bottom of whatever page you're on 8) Notice that there are error messages alerting that library does not have an email address and that the Koha Administrator does not have email address. Both submit buttons will be disabled. 9) Add an email address for your library. You may have to restart memcached again. The error message for the library email address will have disappeared and the Submit button for 'Report to library' will now work. 10) Add an email address for the syspref KohaAdminEmailAddress. You may have to restart memcached again. The error message for the administrator email address will have disappeared and the Submit button for 'Report to Koha Administrator' will not work. 11) First try submitting a problem to the library. Confirm that the fields for 'Problem found on page' and 'Username' are correct, then fill out the 'Subject' and 'Message' and click Submit. 12) Confirm a message shows at the top of the page to show success. 13) Go into mysql and display records from the message_queue table. Confirm that the borrowernumber and subject are correct. Confirm that content shows the message from the problem report, but also the user's username and the problem page. Confirm that the to_address shows the library's email address and the from_address shows the user's email address. 14) Now try submitting a problem to the Koha Admin. Fill fields and click Submit. Confirm message shows at top to show success again. 15) Check message_queue for new problem report. Confirm that the to_address shows the email address from the syspref KohaAdminEmailAddress. Sponsored-by: Catalyst IT Signed-off-by: Josef Moravec --- Koha/ProblemReport.pm | 46 ++++++ Koha/ProblemReports.pm | 55 +++++++ Koha/Schema/Result/Borrower.pm | 15 ++ Koha/Schema/Result/Branch.pm | 16 +- Koha/Schema/Result/ProblemReport.pm | 178 +++++++++++++++++++++ .../bug-4461_add-problem-reports-table.sql | 15 ++ installer/data/mysql/kohastructure.sql | 20 +++ .../bootstrap/en/includes/opac-bottom.inc | 3 + .../bootstrap/en/modules/opac-reportproblem.tt | 129 +++++++++++++++ opac/opac-reportproblem.pl | 100 ++++++++++++ 10 files changed, 576 insertions(+), 1 deletion(-) create mode 100644 Koha/ProblemReport.pm create mode 100644 Koha/ProblemReports.pm create mode 100644 Koha/Schema/Result/ProblemReport.pm create mode 100644 installer/data/mysql/atomicupdate/bug-4461_add-problem-reports-table.sql create mode 100644 koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-reportproblem.tt create mode 100755 opac/opac-reportproblem.pl diff --git a/Koha/ProblemReport.pm b/Koha/ProblemReport.pm new file mode 100644 index 0000000..b9df4ba --- /dev/null +++ b/Koha/ProblemReport.pm @@ -0,0 +1,46 @@ +package Koha::ProblemReport; + +# This file is part of Koha. +# +# Copyright 2017 Aleisha Amohia +# +# 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, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +use Carp; + +use Koha::Database; + +use base qw(Koha::Object); + +=head1 NAME + +Koha::ProblemReport - Koha Problem Report Object class + +=head1 API + +=head2 Class Methods + +=cut + +=head3 type + +=cut + +sub _type { + return 'ProblemReport'; +} + +1; diff --git a/Koha/ProblemReports.pm b/Koha/ProblemReports.pm new file mode 100644 index 0000000..402d91c --- /dev/null +++ b/Koha/ProblemReports.pm @@ -0,0 +1,55 @@ +package Koha::ProblemReports; + +# This file is part of Koha. +# +# Copyright 2017 Aleisha Amohia +# +# 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, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +use Carp; + +use Koha::Database; +use Koha::ProblemReport; + +use base qw(Koha::Objects); + +=head1 NAME + +Koha::ProblemReports - Koha Problem Report Object set class + +=head1 API + +=head2 Class Methods + +=cut + +=head3 type + +=cut + +sub _type { + return 'ProblemReport'; +} + +=head3 object_class + +=cut + +sub object_class { + return 'Koha::ProblemReport'; +} + +1; diff --git a/Koha/Schema/Result/Borrower.pm b/Koha/Schema/Result/Borrower.pm index e50268d..10a2570 100644 --- a/Koha/Schema/Result/Borrower.pm +++ b/Koha/Schema/Result/Borrower.pm @@ -1167,6 +1167,21 @@ __PACKAGE__->might_have( { cascade_copy => 0, cascade_delete => 0 }, ); +=head2 problem_reports + +Type: has_many + +Related object: L + +=cut + +__PACKAGE__->has_many( + "problem_reports", + "Koha::Schema::Result::ProblemReport", + { "foreign.borrowernumber" => "self.borrowernumber" }, + { cascade_copy => 0, cascade_delete => 0 }, +); + =head2 ratings Type: has_many diff --git a/Koha/Schema/Result/Branch.pm b/Koha/Schema/Result/Branch.pm index b4960ef..4f0694b 100644 --- a/Koha/Schema/Result/Branch.pm +++ b/Koha/Schema/Result/Branch.pm @@ -540,6 +540,21 @@ __PACKAGE__->has_many( { cascade_copy => 0, cascade_delete => 0 }, ); +=head2 problem_reports + +Type: has_many + +Related object: L + +=cut + +__PACKAGE__->has_many( + "problem_reports", + "Koha::Schema::Result::ProblemReport", + { "foreign.branchcode" => "self.branchcode" }, + { cascade_copy => 0, cascade_delete => 0 }, +); + =head2 reserves Type: has_many @@ -599,7 +614,6 @@ __PACKAGE__->many_to_many("categorycodes", "branchrelations", "categorycode"); # Created by DBIx::Class::Schema::Loader v0.07042 @ 2017-04-26 16:17:25 # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:99U1YQ4iSum4LbBha4hDTQ - # You can replace this text with custom code or comments, and it will be preserved on regeneration sub koha_objects_class { diff --git a/Koha/Schema/Result/ProblemReport.pm b/Koha/Schema/Result/ProblemReport.pm new file mode 100644 index 0000000..a1ac4bb --- /dev/null +++ b/Koha/Schema/Result/ProblemReport.pm @@ -0,0 +1,178 @@ +use utf8; +package Koha::Schema::Result::ProblemReport; + +# Created by DBIx::Class::Schema::Loader +# DO NOT MODIFY THE FIRST PART OF THIS FILE + +=head1 NAME + +Koha::Schema::Result::ProblemReport + +=cut + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; + +=head1 TABLE: C + +=cut + +__PACKAGE__->table("problem_reports"); + +=head1 ACCESSORS + +=head2 id + + data_type: 'integer' + is_auto_increment: 1 + is_nullable: 0 + +=head2 title + + data_type: 'varchar' + default_value: (empty string) + is_nullable: 0 + size: 40 + +=head2 content + + data_type: 'varchar' + default_value: (empty string) + is_nullable: 0 + size: 255 + +=head2 borrowernumber + + data_type: 'integer' + is_foreign_key: 1 + is_nullable: 1 + +=head2 branchcode + + data_type: 'varchar' + default_value: (empty string) + is_foreign_key: 1 + is_nullable: 0 + size: 10 + +=head2 username + + data_type: 'varchar' + is_nullable: 1 + size: 75 + +=head2 problempage + + data_type: 'varchar' + is_nullable: 1 + size: 255 + +=head2 recipient + + data_type: 'enum' + default_value: 'library' + extra: {list => ["admin","library"]} + is_nullable: 0 + +=head2 reportdate + + data_type: 'datetime' + datetime_undef_if_invalid: 1 + is_nullable: 1 + +=cut + +__PACKAGE__->add_columns( + "id", + { data_type => "integer", is_auto_increment => 1, is_nullable => 0 }, + "title", + { data_type => "varchar", default_value => "", is_nullable => 0, size => 40 }, + "content", + { data_type => "varchar", default_value => "", is_nullable => 0, size => 255 }, + "borrowernumber", + { data_type => "integer", is_foreign_key => 1, is_nullable => 1 }, + "branchcode", + { + data_type => "varchar", + default_value => "", + is_foreign_key => 1, + is_nullable => 0, + size => 10, + }, + "username", + { data_type => "varchar", is_nullable => 1, size => 75 }, + "problempage", + { data_type => "varchar", is_nullable => 1, size => 255 }, + "recipient", + { + data_type => "enum", + default_value => "library", + extra => { list => ["admin", "library"] }, + is_nullable => 0, + }, + "reportdate", + { + data_type => "datetime", + datetime_undef_if_invalid => 1, + is_nullable => 1, + }, +); + +=head1 PRIMARY KEY + +=over 4 + +=item * L + +=back + +=cut + +__PACKAGE__->set_primary_key("id"); + +=head1 RELATIONS + +=head2 borrowernumber + +Type: belongs_to + +Related object: L + +=cut + +__PACKAGE__->belongs_to( + "borrowernumber", + "Koha::Schema::Result::Borrower", + { borrowernumber => "borrowernumber" }, + { + is_deferrable => 1, + join_type => "LEFT", + on_delete => "CASCADE", + on_update => "CASCADE", + }, +); + +=head2 branchcode + +Type: belongs_to + +Related object: L + +=cut + +__PACKAGE__->belongs_to( + "branchcode", + "Koha::Schema::Result::Branch", + { branchcode => "branchcode" }, + { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" }, +); + + +# Created by DBIx::Class::Schema::Loader v0.07042 @ 2017-01-12 22:06:40 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:Gh48Q5QmR+oI4oI0c6Hizg + + +# You can replace this text with custom code or comments, and it will be preserved on regeneration +1; diff --git a/installer/data/mysql/atomicupdate/bug-4461_add-problem-reports-table.sql b/installer/data/mysql/atomicupdate/bug-4461_add-problem-reports-table.sql new file mode 100644 index 0000000..5a25c65 --- /dev/null +++ b/installer/data/mysql/atomicupdate/bug-4461_add-problem-reports-table.sql @@ -0,0 +1,15 @@ +DROP TABLE IF EXISTS `problem_reports`; +CREATE TABLE `problem_reports` ( -- problems reported by users through OPAC + `id` int(11) NOT NULL auto_increment, -- unqiue identifier assigned by Koha + `title` varchar(40) NOT NULL default '', -- report subject line + `content` varchar(255) NOT NULL default '', -- report message content + `borrowernumber` int(11) default NULL, -- the user who created the problem report + `branchcode` varchar(10) NOT NULL default '', -- borrower's branch + `username` varchar(75) default NULL, -- OPAC username + `problempage` varchar(255) default NULL, -- page the user triggered the problem report form from + `recipient` enum('admin','library') NOT NULL default 'library', -- the 'to-address' of the problem report + `reportdate` datetime default NULL, -- date and time of report submission + PRIMARY KEY (`id`), + CONSTRAINT `problem_reports_ibfk1` FOREIGN KEY (`borrowernumber`) REFERENCES `borrowers` (`borrowernumber`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `problem_reports_ibfk2` FOREIGN KEY (`branchcode`) REFERENCES `branches` (`branchcode`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index e227125..b130d12 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -1412,6 +1412,26 @@ CREATE TABLE `printers_profile` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -- +-- Table structure for table `problem_reports` +-- + +DROP TABLE IF EXISTS `problem_reports`; +CREATE TABLE `problem_reports` ( -- problems reported by users through OPAC + `id` int(11) NOT NULL auto_increment, -- unqiue identifier assigned by Koha + `title` varchar(40) NOT NULL default '', -- report subject line + `content` varchar(255) NOT NULL default '', -- report message content + `borrowernumber` int(11) default NULL, -- the user who created the problem report + `branchcode` varchar(10) NOT NULL default '', -- borrower's branch + `username` varchar(75) default NULL, -- OPAC username + `problempage` varchar(255) default NULL, -- page the user triggered the problem report form from + `recipient` enum('admin','library') NOT NULL default 'library', -- the 'to-address' of the problem report + `reportdate` datetime default NULL, -- date and time of report submission + PRIMARY KEY (`id`), + CONSTRAINT `problem_reports_ibfk1` FOREIGN KEY (`borrowernumber`) REFERENCES `borrowers` (`borrowernumber`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `problem_reports_ibfk2` FOREIGN KEY (`branchcode`) REFERENCES `branches` (`branchcode`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; + +-- -- Table structure for table `repeatable_holidays` -- diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-bottom.inc b/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-bottom.inc index 80626e0..633847d 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-bottom.inc +++ b/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-bottom.inc @@ -16,6 +16,9 @@
+

Powered by [% IF template.name.match('opac-main.tt') %] diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-reportproblem.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-reportproblem.tt new file mode 100644 index 0000000..f36c745 --- /dev/null +++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-reportproblem.tt @@ -0,0 +1,129 @@ +[% USE Koha %] +[% INCLUDE 'doc-head-open.inc' %] +[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog › Report a Problem +[% INCLUDE 'doc-head-close.inc' %] +[% BLOCK cssinclude %][% END %] + +[% INCLUDE 'bodytag.inc' bodyid='opac-reportproblem' bodyclass='scrollto' %] +[% INCLUDE 'masthead.inc' %] + +

+ + +
+
+ [% IF ( OpacNav || OpacNavBottom ) %] +
+ +
+
+ [% ELSE %] +
+ [% END %] +

Report a problem

+ [% IF ( successfuladd ) %] +
Your problem report has been sent to the [% IF ( recipient == 'admin' ) %]Koha Administrator[% ELSE %] [% recipient %][% END %].
+ [% END %] + [% IF ( nolibemail ) %] +
Your library has not provided an email address.
+ [% END %] + [% IF ( noadminemail ) %] +
The Koha Administrator has not provided an email address.
+ [% END %] + [% IF ( nolibemail && noadminemail ) %] +
Unable to send problem reports.
+ [% END %] +
+ +
+
+ + +
+
    +
  1. + + + [% probpage | html %] +
  2. +
  3. + + + [% username | html %] +
  4. + + +
  5. +
  6. + + +
  7. +
+
+
+ [% IF ( nolibemail ) %] + + [% ELSE %] + + [% END %] +
+
+
+
+
+ + +
+
    +
  1. + + + [% probpage | html %] +
  2. +
  3. + + + [% username | html %] +
  4. + + +
  5. +
  6. + + +
  7. +
+
+
+ [% IF ( noadminemail ) %] + + [% ELSE %] + + [% END %] +
+
+
+
+
+
+
+
+ +[% INCLUDE 'opac-bottom.inc' %] +[% BLOCK jsinclude %] + + + +[% END %] diff --git a/opac/opac-reportproblem.pl b/opac/opac-reportproblem.pl new file mode 100755 index 0000000..b4ed191 --- /dev/null +++ b/opac/opac-reportproblem.pl @@ -0,0 +1,100 @@ +#!/usr/bin/perl + +# This file is part of Koha. +# +# Copyright 2017 Aleisha Amohia +# +# 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 CGI qw ( -utf8 ); +use C4::Auth; # get_template_and_user +use C4::Output; +use C4::Members; +use C4::Letters; +use Koha::ProblemReport; +use Koha::DateUtils; +use Koha::Libraries; + +my $input = new CGI; + +my ( $template, $borrowernumber, $cookie ) = get_template_and_user( + { + template_name => "opac-reportproblem.tt", + type => "opac", + query => $input, + authnotrequired => 0, + } +); + +my $problempage = $ENV{HTTP_REFERER}; +my $member = GetMember( borrowernumber => $borrowernumber ); +my $username = $member->{'userid'}; +my $branchcode = $member->{'branchcode'}; +my $library = Koha::Libraries->find($branchcode); +if ( $library->branchemail eq undef || ! $library->branchemail ) { + $template->param( nolibemail => 1 ); +} +my $koha_admin = C4::Context->preference('KohaAdminEmailAddress'); +if ( ! $koha_admin ) { + $template->param( noadminemail => 1 ); +} +my $recipient = $input->param('recipient') || 'library'; +$template->param( + username => $username, + probpage => $problempage, +); + +my $op = $input->param('op') || ''; +if ( $op eq 'addreport' ) { + my $subject = $input->param('subject'); + my $message = $input->param('message'); + my $place = $input->param('place'); + my $problem = Koha::ProblemReport->new({ title => $subject, content => $message, borrowernumber => $borrowernumber, branchcode => $branchcode, username => $username, problempage => $place, recipient => $recipient, reportdate => dt_from_string() })->store; + $template->param( + recipient => $recipient, + successfuladd => 1, + probpage => $place, + ); + + my $problemreport = $problem->unblessed; + $problemreport->{code} = 'PROBLEM_REPORT'; + $problemreport->{content} .= "\nUsername: $username"; + $problemreport->{content} .= "\nProblem page: $place"; + my $transport = 'email'; + + my $from_address = $member->{email} || $member->{emailpro} || $member->{B_email} || $koha_admin; + + if ( $recipient eq 'admin' ) { + C4::Letters::EnqueueLetter({ + letter => $problemreport, + borrowernumber => $borrowernumber, + message_transport_type => $transport, + to_address => $koha_admin, + from_address => $from_address, + }); + } else { + my $to_address = $library->branchemail; + C4::Letters::EnqueueLetter({ + letter => $problemreport, + borrowernumber => $borrowernumber, + message_transport_type => $transport, + to_address => $to_address, + from_address => $from_address, + }); + } +} + +output_html_with_http_headers $input, $cookie, $template->output; -- 2.1.4