From 6713a2ae6b207cbb1b3c80e1c1191e63509c6d83 Mon Sep 17 00:00:00 2001 From: Olli-Antti Kivilahti Date: Mon, 23 Apr 2018 18:04:13 +0000 Subject: [PATCH] Bug 1985: Send email alert when comment posted. Many blog systems have a feature where the admin gets an email when someone posts a new comment that needs to be moderated. It would be nice to incorporate this into Koha. Ideally, you could set an email address in system preferences where notifications should be sent (since the Koha administrator is probably not the one approving comments). The body of the email would contain the comments, and offer a direct link to approve or delete the comment. The authorship was corrected to Olli-Antti Kivilahti. In comment #11, it was mentioned that title and biblionumber from the biblio table were not available as variables in the letter. This corrects this by converting the parameter list to a hashref, and adding the missing biblio number. It also cleans up the license on C4/Review.pm to be in line with the current coding guidelines license. Also strict and warning have been changed to the 'Use Modern::Perl;' now. Additionally, <> is now usable in the letter, as is <>. These were required additions, because comment #1 expressly says there should be a direct link to approve or delete. I also included a review everything link, since there could be multiple comments outstanding. The default letter was tweaked as well to reflect these changes. Fixed bad URLs as noted in comment #26. TEST PLAN --------- 1) Create test branch and apply patch 2) run installer/data/mysql/updatedatabase.pl -- this will add the required default letter. 3) In the staff client: a) set the CommentModeratorsEmail system preference. -- not setting it will mean you won't get any queued letters. a) set the staffClientBaseURL system preference. -- not setting it will mean your email links won't be valid (i.e http:///...). b) modify the COMMENT_CREATED default letter as desired. -- feel free to add other things. 4) In the OPAC: a) Log in b) Find something c) Click on the 'Comments' tab -- Holdings/Title notes/Comments (#) is at the bottom d) Click 'Post or edit your comments on this item' e) In the window that pops up, type your comment. f) Click 'Submit and close this window'. g) Click 'Edit' and repeat steps e and f again. 5) In a mysql client: a) Open the koha database b) SELECT * FROM message_queue WHERE letter_code='COMMENT_CREATED'; -- There should be at least two. -- They should be able to contain the borrower number, biblio title, and other borrower and biblio related things. -- Comments are at a biblio level, so items, and issues don't make sense as variables for the letter. -- Confirm the URLs are valid by pasting into a browser. 6) prove -v t/db_dependent/Koha/Reviews.t -- six new tests should run. 7) Run the koha qa test tool. Signed-off-by: Andrew Fuerste-Henry --- C4/Letters.pm | 5 ++- Koha/Review.pm | 51 +++++++++++++++++++++- installer/data/mysql/atomicupdate/bug_1985.sql | 38 ++++++++++++++++ .../data/mysql/en/mandatory/sample_notices.sql | 25 +++++++++++ installer/data/mysql/sysprefs.sql | 1 + .../prog/en/modules/admin/preferences/opac.pref | 4 ++ opac/opac-review.pl | 27 +++++++++--- t/db_dependent/Koha/Reviews.t | 43 +++++++++++++++++- 8 files changed, 185 insertions(+), 9 deletions(-) create mode 100644 installer/data/mysql/atomicupdate/bug_1985.sql diff --git a/C4/Letters.pm b/C4/Letters.pm index bdb213a49e..6232fa4b62 100644 --- a/C4/Letters.pm +++ b/C4/Letters.pm @@ -631,8 +631,10 @@ sub GetPreparedLetter { } } - my $OPACBaseURL = C4::Context->preference('OPACBaseURL'); + my $OPACBaseURL = C4::Context->preference('OPACBaseURL') // q{}; $letter->{content} =~ s/<>/$OPACBaseURL/go; + my $staff_client_base_url = C4::Context->preference('staffClientBaseURL') // q{}; + $letter->{content} =~ s/<>/$staff_client_base_url/go; if ($want_librarian) { # parsing librarian name @@ -754,6 +756,7 @@ sub _parseletter_sth { ($table eq 'aqbooksellers') ? "SELECT * FROM $table WHERE id = ?" : ($table eq 'aqorders' ) ? "SELECT * FROM $table WHERE ordernumber = ?" : ($table eq 'opac_news' ) ? "SELECT * FROM $table WHERE idnew = ?" : + ($table eq 'reviews' ) ? "SELECT * FROM $table WHERE reviewid = ?" : ($table eq 'article_requests') ? "SELECT * FROM $table WHERE id = ?" : ($table eq 'borrower_modifications') ? "SELECT * FROM $table WHERE verification_token = ?" : ($table eq 'subscription') ? "SELECT * FROM $table WHERE subscriptionid = ?" : diff --git a/Koha/Review.pm b/Koha/Review.pm index 72e3e2fb3b..e2e6b32e06 100644 --- a/Koha/Review.pm +++ b/Koha/Review.pm @@ -19,7 +19,9 @@ use Modern::Perl; use Carp; -use Koha::Database; +# Koha::Database is used in the nested mess of C4::Letters; +# As is C4::Context. +use C4::Letters; use base qw(Koha::Object); @@ -67,4 +69,51 @@ sub _type { return 'Review'; } +=head3 SendReviewAlert + + $review->SendReviewAlert($parameters); + +Queue an outgoing email alert when a borrower posts a review, +using the passed parameters in a hash reference. + +=cut + +sub SendReviewAlert { + my ( $self, $params ) = @_; + + my $borrowernumber = $params->{borrowernumber}; + my $reviewid = $params->{reviewid}; + my $biblionumber = $params->{biblionumber}; + + my $moderatorEmail = C4::Context->preference('CommentModeratorsEmail'); + unless ($moderatorEmail) { + carp 'CommentModeratorsEmail is not set!'; + return; + } + + my $letter = C4::Letters::GetPreparedLetter ( + module => 'members', + letter_code => 'COMMENT_CREATED', + tables => { + 'reviews' => $reviewid, + 'borrowers' => $borrowernumber, + 'biblio' => $biblionumber, + 'biblioitems' => $biblionumber, + } + ); + unless ($letter) { + carp 'COMMENT_CREATED member letter not found!'; + return; + } + + C4::Letters::EnqueueLetter({ + letter => $letter, + borrowernumber => $borrowernumber, + message_transport_type => 'email', + to_address => $moderatorEmail, + }); + + return 1; +} + 1; diff --git a/installer/data/mysql/atomicupdate/bug_1985.sql b/installer/data/mysql/atomicupdate/bug_1985.sql new file mode 100644 index 0000000000..6c23ef1fb0 --- /dev/null +++ b/installer/data/mysql/atomicupdate/bug_1985.sql @@ -0,0 +1,38 @@ +INSERT IGNORE INTO letter + (module, code, branchcode, name, is_html, + title, + content, message_transport_type) +VALUES + ('members', 'COMMENT_CREATED', '', 'Comment created notification', '0', + 'Comment from <> is waiting for moderation', +'Dear moderator, + +We want to inform you that borrower <> has just created a new comment on <>, which is biblionumber <>. + +--- BEGIN COMMENT --- +<> +--- END COMMENT --- + +To approve: +http://<>/cgi-bin/koha/reviews/reviewswaiting.pl?op=approve&reviewid=<> + +To delete: +http://<>/cgi-bin/koha/reviews/reviewswaiting.pl?op=delete&reviewid=<> + +Or to review all comments: +http://<>/cgi-bin/koha/reviews/reviewswaiting.pl + +Check it out! + +Your library.', +'email' + ); + +INSERT IGNORE INTO systempreferences + (variable, value,options, + explanation, + type) +VALUES + ('CommentModeratorsEmail','', '', + 'The email address where to send a notification (template code COMMENT_CREATED) when a Borrower adds/modifies a review/comment for a Biblio. Set to empty to disable sending email notifications.', + 'Textarea'); diff --git a/installer/data/mysql/en/mandatory/sample_notices.sql b/installer/data/mysql/en/mandatory/sample_notices.sql index 6d676e73e6..658fb14b24 100644 --- a/installer/data/mysql/en/mandatory/sample_notices.sql +++ b/installer/data/mysql/en/mandatory/sample_notices.sql @@ -156,6 +156,31 @@ Your library account has been created. Please verify your email address by click If you did not initiate this request, you may safely ignore this one-time message. The request will expire shortly.' ); +INSERT INTO letter (module, code, branchcode, name, is_html, title, content, message_transport_type) +VALUES ( 'members', 'COMMENT_CREATED', '', 'Comment created notification', '0', 'Comment from <> is waiting for moderation', +'Dear moderator, + +We want to inform you that borrower <> has just created a new comment on <>, which is biblionumber <>. + +--- BEGIN COMMENT --- +<> +--- END COMMENT --- + +To approve: +http://<>/cgi-bin/koha/reviews/reviewswaiting.pl?op=approve&reviewid=<> + +To delete: +http://<>/cgi-bin/koha/reviews/reviewswaiting.pl?op=delete&reviewid=<> + +Or to review all comments: +http://<>/cgi-bin/koha/reviews/reviewswaiting.pl + +Check it out! + +Your library.', +'email' +); + INSERT INTO letter (module, code, branchcode, name, is_html, title, content) VALUES ('members', 'SHARE_INVITE', '', 'Invitation for sharing a list', '0', 'Share list <>', 'Dear patron, diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index a0d1132d25..dedfb0c6eb 100644 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -122,6 +122,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` ('CoceHost', '', NULL, 'Coce server URL', 'Free'), ('CoceProviders', '', 'aws,gb,ol', 'Coce providers', 'multiple'), ('COinSinOPACResults','1','','If ON, use COinS in OPAC search results page. NOTE: this can slow down search response time significantly','YesNo'), +('CommentModeratorsEmail','','','The email address where to send a notification (template code COMMENT_CREATED) when a Borrower adds/modifies a review/comment for a Biblio. Set to empty to disable sending email notifications.','Textarea'), ('ConfirmFutureHolds','0','','Number of days for confirming future holds','Integer'), ('ConsiderOnSiteCheckoutsAsNormalCheckouts','1',NULL,'Consider on-site checkouts as normal checkouts','YesNo'), ('CronjobLog','0',NULL,'If ON, log information from cron jobs.','YesNo'), diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref index 567e62276d..14dfe70cd3 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref @@ -470,6 +470,10 @@ OPAC: no: Hide - reviewer's avatar beside comments in OPAC. The avatar will be searched on www.libravatar.org using the patron's e-mail address. - + - The email address where to send a notification (template code COMMENT_CREATED) when a Borrower adds/modifies a review/comment for a Biblio. Set to empty to disable sending email notifications. + - pref: CommentModeratorsEmail + class: textarea + - - pref: RequestOnOpac choices: yes: Allow diff --git a/opac/opac-review.pl b/opac/opac-review.pl index 841810f8d8..aead1144c3 100755 --- a/opac/opac-review.pl +++ b/opac/opac-review.pl @@ -33,8 +33,8 @@ use Koha::Reviews; my $query = new CGI; my $biblionumber = $query->param('biblionumber'); -my $review = $query->param('review'); -my $reviewid = $query->param('reviewid'); +my $review = $query->param('review'); # if defined submit +my $reviewid = $query->param('reviewid'); # if defined edit my ( $template, $borrowernumber, $cookie ) = get_template_and_user( { template_name => "opac-review.tt", @@ -46,7 +46,11 @@ my ( $template, $borrowernumber, $cookie ) = get_template_and_user( # FIXME: need to allow user to delete their own comment(s) -my ( $clean, @errors, $savedreview ); +my ( $clean, @errors, $savedreview, $affectedreview ); + +my $submitting = ( defined $review && $review ne q{} ) ? 1 : 0; +my $editing = ( defined $reviewid ) ? 1 : 0; + my $biblio = Koha::Biblios->find( $biblionumber ); if( !$biblio ) { @@ -60,7 +64,7 @@ if( !$biblio ) { $review = $savedreview? $savedreview->review: $review; } -if( !@errors && defined $review ) { +if( !@errors && $submitting ) { if ($review !~ /\S/) { push @errors, {empty=>1}; } else { @@ -79,15 +83,26 @@ if( !@errors && defined $review ) { datereviewed => dt_from_string } )->store; + $affectedreview = $savedreview; } else { - $reviewid = Koha::Review->new( + my $newreview = Koha::Review->new( { biblionumber => $biblionumber, borrowernumber => $borrowernumber, review => $clean, datereviewed => dt_from_string } - )->store->reviewid; + )->store; + $reviewid = $newreview ? $newreview->reviewid : 0; + $affectedreview = $newreview; } + if ($reviewid) { + $affectedreview->SendReviewAlert({ + 'borrowernumber' => $borrowernumber, + 'reviewid' => $reviewid, + 'biblionumber' => $biblionumber + }); + } + unless (@errors){ $template->param(WINDOW_CLOSE=>1); } } } diff --git a/t/db_dependent/Koha/Reviews.t b/t/db_dependent/Koha/Reviews.t index 9a51775ebb..6dd859498b 100644 --- a/t/db_dependent/Koha/Reviews.t +++ b/t/db_dependent/Koha/Reviews.t @@ -19,10 +19,13 @@ use Modern::Perl; -use Test::More tests => 8; +use Test::More tests => 14; +use Test::Warn; use Koha::Patrons; use Koha::Reviews; +use Koha::Notice::Messages; +use Koha::Notice::Templates; use Koha::Database; use t::lib::TestBuilder; @@ -38,6 +41,7 @@ $patron_1 = Koha::Patrons->find( $patron_1->{borrowernumber} ); $patron_2 = Koha::Patrons->find( $patron_2->{borrowernumber} ); my $biblio_1 = $builder->build({ source => 'Biblio' }); my $biblio_2 = $builder->build({ source => 'Biblio' }); +my $nb_of_messages = Koha::Notice::Messages->search->count; my $nb_of_reviews = Koha::Reviews->search->count; my $nb_of_approved_reviews = Koha::Reviews->search({ approved => 1 })->count; my $new_review_1_1 = Koha::Review->new({ @@ -83,4 +87,41 @@ subtest 'search_limited' => sub { $retrieved_review_1_1->delete; is( Koha::Reviews->search->count, $nb_of_reviews + 2, 'Delete should have deleted the review' ); +# Test SendReview Alert + +# empty CommentModeratorsEmail +t::lib::Mocks::mock_preference('CommentModeratorsEmail',undef); +warning_like { +$new_review_1_2->SendReviewAlert({ + borrowernumber => $patron_1->{borrowernumber}, + biblionumber => $biblio_2->{biblionumber}, + reviewid => $new_review_1_2->reviewid +}) } qr/CommentModeratorsEmail is not set!/, 'SendReviewAlert triggered expected CommentModeratorsEmail warning.'; +is( Koha::Notice::Messages->search->count, $nb_of_messages, 'SendReviewAlert lacking CommentModeratorsEmail triggered nothing.' ); + +# set CommentModeratorsEmail +t::lib::Mocks::mock_preference('CommentModeratorsEmail','test@test.test'); +warning_is { +$new_review_1_2->SendReviewAlert({ + borrowernumber => $patron_1->{borrowernumber}, + biblionumber => $biblio_2->{biblionumber}, + reviewid => $new_review_1_2->reviewid +}) } '', 'SendReviewAlert triggered no warnings as expected.'; +is( Koha::Notice::Messages->search->count, $nb_of_messages+1, 'SendReviewAlert triggered notice.' ); + +# letter missing +Koha::Notice::Templates->search({ + module => 'members', + code => 'COMMENT_CREATED' +})->delete; +warnings_like { +$new_review_1_2->SendReviewAlert({ + borrowernumber => $patron_1->{borrowernumber}, + biblionumber => $biblio_2->{biblionumber}, + reviewid => $new_review_1_2->reviewid +}) } +[ qr/No members COMMENT_CREATED letter transported by email/, + qr/COMMENT_CREATED member letter not found!/ ] , 'SendReviewAlert triggered expected COMMENT_CREATED warnings.'; +is( Koha::Notice::Messages->search->count, $nb_of_messages+1, 'SendReviewAlert lacking letter triggered nothing new.' ); + $schema->storage->txn_rollback; -- 2.11.0