From fbb0a82bdee031cf7ffb7f0a407b40a52bc8004a Mon Sep 17 00:00:00 2001 From: Kyle M Hall Date: Wed, 24 Aug 2022 13:54:49 -0400 Subject: [PATCH] Bug 31453: Add ability to filter messages to process using process_message_queue.pl via a command line parameter It would be very useful to be able to tell process_message_queue.pl to skip processing some messages. This is particularly useful where a plugin handles sending some message using the before_send_messages hook, but while that plugin is processing, more messages meant for the plugin might be queued. At that point, control moves back to the script and SendQueuedMessages is called, and those messages end up being processed there instead of by the plugin. Test Plan: 1) Apply this patch 2) Queue two messages, each with a unique word 3) Run process_message_queue --where "content NOT LIKE '%WORD%'" where WORD is a unique word in one of the two message 4) Note the message containing "WORD" was not processed 5) prove t/db_dependent/Letters.t --- C4/Letters.pm | 16 ++++--- misc/cronjobs/process_message_queue.pl | 4 ++ t/db_dependent/Letters.t | 63 +++++++++++++++++++++++++- 3 files changed, 76 insertions(+), 7 deletions(-) diff --git a/C4/Letters.pm b/C4/Letters.pm index 4d60753cc6..b0d82edb8b 100644 --- a/C4/Letters.pm +++ b/C4/Letters.pm @@ -972,12 +972,13 @@ Returns number of messages sent. sub SendQueuedMessages { my $params = shift; - my $which_unsent_messages = { - 'message_id' => $params->{'message_id'}, - 'limit' => $params->{'limit'} // 0, - 'borrowernumber' => $params->{'borrowernumber'} // q{}, - 'letter_code' => $params->{'letter_code'} // q{}, - 'message_transport_type' => $params->{'type'} // q{}, + my $which_unsent_messages = { + 'message_id' => $params->{'message_id'}, + 'limit' => $params->{'limit'} // 0, + 'borrowernumber' => $params->{'borrowernumber'} // q{}, + 'letter_code' => $params->{'letter_code'} // q{}, + 'message_transport_type' => $params->{'type'} // q{}, + 'where' => $params->{'where'} // q{}, }; my $unsent_messages = _get_unsent_messages( $which_unsent_messages ); MESSAGE: foreach my $message ( @$unsent_messages ) { @@ -1281,6 +1282,9 @@ sub _get_unsent_messages { $statement .= ' AND message_id = ?'; push @query_params, $params->{message_id}; } + if ( $params->{where} ) { + $statement .= " AND $params->{where} "; + } if ( $params->{'limit'} ) { $statement .= ' limit ? '; push @query_params, $params->{'limit'}; diff --git a/misc/cronjobs/process_message_queue.pl b/misc/cronjobs/process_message_queue.pl index 9250748908..9250ec503a 100755 --- a/misc/cronjobs/process_message_queue.pl +++ b/misc/cronjobs/process_message_queue.pl @@ -32,6 +32,7 @@ my $limit = undef; my $method = 'LOGIN'; my $help = 0; my $verbose = 0; +my $where; my @type; my @letter_code; @@ -46,6 +47,7 @@ GetOptions( 'v|verbose' => \$verbose, 't|type:s' => \@type, 'c|code:s' => \@letter_code, + 'w|where:s' => \$where, ); my $usage = << 'ENDUSAGE'; @@ -64,6 +66,7 @@ This script has the following parameters : -m --method: authentication method required by SMTP server (See perldoc Sendmail.pm for supported authentication types.) -h --help: this message -v --verbose: provides verbose output to STDOUT + -w --where: filter messages to send with additional conditions in the where clause ENDUSAGE die $usage if $help; @@ -116,6 +119,7 @@ C4::Letters::SendQueuedMessages( limit => $limit, type => \@type, letter_code => \@letter_code, + where => $where, } ); diff --git a/t/db_dependent/Letters.t b/t/db_dependent/Letters.t index 814d5e60e9..78f6e6832e 100755 --- a/t/db_dependent/Letters.t +++ b/t/db_dependent/Letters.t @@ -18,7 +18,7 @@ # along with Koha; if not, see . use Modern::Perl; -use Test::More tests => 85; +use Test::More tests => 86; use Test::MockModule; use Test::Warn; use Test::Exception; @@ -906,6 +906,67 @@ EOF is( $items_content, $expected_items_content, 'get_item_content should return correct items info without time (if dateonly => 1)' ); }; +subtest 'Test where parameter for SendQueuedMessages' => sub { + plan tests => 1; + + my $dbh = C4::Context->dbh; + + my $borrowernumber = Koha::Patron->new({ + firstname => 'Jane', + surname => 'Smith', + categorycode => $patron_category, + branchcode => $library->{branchcode}, + dateofbirth => $date, + smsalertnumber => undef, + })->store->borrowernumber; + + $dbh->do(q|DELETE FROM message_queue|); + $my_message = { + 'letter' => { + 'content' => 'a message', + 'metadata' => 'metadata', + 'code' => 'TEST_MESSAGE', + 'content_type' => 'text/plain', + 'title' => 'message title' + }, + 'borrowernumber' => $borrowernumber, + 'to_address' => undef, + 'message_transport_type' => 'sms', + 'from_address' => 'from@example.com' + }; + my $my_message2 = { + 'letter' => { + 'content' => 'another message', + 'metadata' => 'metadata', + 'code' => 'TEST_MESSAGE', + 'content_type' => 'text/plain', + 'title' => 'message title' + }, + 'borrowernumber' => $borrowernumber, + 'to_address' => undef, + 'message_transport_type' => 'sms', + 'from_address' => 'from@example.com' + }; + my $my_message3 = { + 'letter' => { + 'content' => 'a skipped message', + 'metadata' => 'metadata', + 'code' => 'TEST_MESSAGE', + 'content_type' => 'text/plain', + 'title' => 'message title' + }, + 'borrowernumber' => $borrowernumber, + 'to_address' => undef, + 'message_transport_type' => 'sms', + 'from_address' => 'from@example.com' + }; + C4::Letters::EnqueueLetter($my_message); + C4::Letters::EnqueueLetter($my_message2); + C4::Letters::EnqueueLetter($my_message3); + my $messages_processed = C4::Letters::SendQueuedMessages( { where => q{content NOT LIKE '%skipped%'} } ); + is( $messages_processed, 2, "Correctly skipped processing one message containing the work 'skipped' in contents" ); +}; + subtest 'Test limit parameter for SendQueuedMessages' => sub { plan tests => 3; -- 2.30.2